Compare commits
643 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
817f3283d1 | ||
|
|
0e0bcacf3c | ||
|
|
0004cc46dd | ||
|
|
1c330177f0 | ||
|
|
014536f5d5 | ||
|
|
ca0f828e7a | ||
|
|
ebad5f840a | ||
|
|
ae2a4507ed | ||
|
|
c1924dc5a1 | ||
|
|
ee3e6112d3 | ||
|
|
2492fc00d4 | ||
|
|
776bbd0ccb | ||
|
|
0e0a310acf | ||
|
|
7d5eeb2135 | ||
|
|
c408c4ad3d | ||
|
|
6ddd10482b | ||
|
|
8e17459fa1 | ||
|
|
c89b326350 | ||
|
|
969549fdf0 | ||
|
|
d63f3a0c0a | ||
|
|
d0518cc250 | ||
|
|
4107c49ecd | ||
|
|
95296dfd67 | ||
|
|
cf5596fc79 | ||
|
|
f2155fadf1 | ||
|
|
02e3e04205 | ||
|
|
50affc546f | ||
|
|
78c09e3afe | ||
|
|
3b7cc05387 | ||
|
|
fb8f44d73f | ||
|
|
ede0665a5a | ||
|
|
1f368e1c18 | ||
|
|
6b7108e347 | ||
|
|
b6ca83ea4c | ||
|
|
f40bdfa66a | ||
|
|
fb35ad15ae | ||
|
|
7bced397c9 | ||
|
|
a692c880f1 | ||
|
|
e5f05d7812 | ||
|
|
35e91daba0 | ||
|
|
9df4801e0b | ||
|
|
2643f27b36 | ||
|
|
6f4dc321c3 | ||
|
|
65255ea304 | ||
|
|
c69fd917e3 | ||
|
|
acea93eda9 | ||
|
|
03251ffbc0 | ||
|
|
d60595d8f2 | ||
|
|
84a10ca019 | ||
|
|
1bdcfa8d37 | ||
|
|
a0eeb9fbf2 | ||
|
|
29da702491 | ||
|
|
53a17c1742 | ||
|
|
65c88a43a2 | ||
|
|
e69d556b63 | ||
|
|
0a90118089 | ||
|
|
adf8b3f64f | ||
|
|
c01664c30c | ||
|
|
7415885fb3 | ||
|
|
89bdd3660c | ||
|
|
4b06c28353 | ||
|
|
cc0aaaa18f | ||
|
|
68bf73f319 | ||
|
|
2d0beef3bb | ||
|
|
13b0a2bf3b | ||
|
|
ef8a4449b1 | ||
|
|
43e60eb681 | ||
|
|
ded9cab35d | ||
|
|
89a7ee7b22 | ||
|
|
787ea57a18 | ||
|
|
f2ac1e2540 | ||
|
|
09775d3718 | ||
|
|
065a752b42 | ||
|
|
7a2b302e68 | ||
|
|
170d24a251 | ||
|
|
70399856c1 | ||
|
|
848a95329c | ||
|
|
54ba4814ae | ||
|
|
07b885318f | ||
|
|
2f9ca4b49d | ||
|
|
8219fbd421 | ||
|
|
9233e5e0ae | ||
|
|
3c7327842c | ||
|
|
b422e3c316 | ||
|
|
d9f0246611 | ||
|
|
89c9427087 | ||
|
|
c8741a400d | ||
|
|
dcc90658fd | ||
|
|
e73a2194b3 | ||
|
|
a80b792afc | ||
|
|
8665fe1957 | ||
|
|
e3b7058110 | ||
|
|
5b117d5526 | ||
|
|
1957c8c881 | ||
|
|
6491fef1e0 | ||
|
|
a116e20c76 | ||
|
|
4ad359ccc6 | ||
|
|
419cf1f1c4 | ||
|
|
9e854f525d | ||
|
|
8175b1532e | ||
|
|
7321ceaf69 | ||
|
|
812f934e77 | ||
|
|
1132b89236 | ||
|
|
4ef4477535 | ||
|
|
a022d39d2a | ||
|
|
bd6db6f226 | ||
|
|
666468cc36 | ||
|
|
72290ede0e | ||
|
|
4abcbb056e | ||
|
|
0bce9c9808 | ||
|
|
627631bf9a | ||
|
|
e899e3d745 | ||
|
|
7109b7c066 | ||
|
|
3010ec11ae | ||
|
|
8fc8de382a | ||
|
|
c0fc4d2122 | ||
|
|
0c4fa6ee0a | ||
|
|
7078ed1e0b | ||
|
|
a8dd8ce6c9 | ||
|
|
4e1f674c41 | ||
|
|
15a64f9e7f | ||
|
|
e28deeb8e9 | ||
|
|
7b686d8bd6 | ||
|
|
7ed1df2e80 | ||
|
|
0c83b98105 | ||
|
|
c80788a3ac | ||
|
|
97f79e3b27 | ||
|
|
075ed522be | ||
|
|
e047a3acc6 | ||
|
|
981bb8f9d1 | ||
|
|
f6f14a2a83 | ||
|
|
29df94eb4a | ||
|
|
6ceddd9205 | ||
|
|
77c6cc9857 | ||
|
|
d40c58dc3b | ||
|
|
1f15ea5955 | ||
|
|
30f3ea4bd3 | ||
|
|
2eee4c67f5 | ||
|
|
2eaea70111 | ||
|
|
a5f9ef8b7f | ||
|
|
b44d7f78e0 | ||
|
|
189a01f7a7 | ||
|
|
e5905c4b84 | ||
|
|
bd2d0079c9 | ||
|
|
4c210a29bc | ||
|
|
1d7d94ed7d | ||
|
|
e27ca53091 | ||
|
|
664d361fa5 | ||
|
|
03af2940f7 | ||
|
|
ea3d49506f | ||
|
|
a926a26f0c | ||
|
|
690ca8c238 | ||
|
|
5686d9162e | ||
|
|
c089196e15 | ||
|
|
300d6ef45c | ||
|
|
d4f31a5b3e | ||
|
|
411a66476d | ||
|
|
3efab2039f | ||
|
|
baff19767d | ||
|
|
53a4bda9ba | ||
|
|
f2c4949707 | ||
|
|
37bf59067f | ||
|
|
e638841f5a | ||
|
|
61ca915ac5 | ||
|
|
6d03bbea96 | ||
|
|
add4ab4bf0 | ||
|
|
4da831c02f | ||
|
|
421c6cf951 | ||
|
|
a72065a108 | ||
|
|
4445cee19d | ||
|
|
aa15bc445e | ||
|
|
9a9e163e71 | ||
|
|
05e2adf509 | ||
|
|
7ff33fae6f | ||
|
|
17efd59252 | ||
|
|
e4e3212122 | ||
|
|
3b3d3e5cd4 | ||
|
|
21d88b4525 | ||
|
|
d80df2c8a0 | ||
|
|
6974df39a7 | ||
|
|
7668f77439 | ||
|
|
efbbcade43 | ||
|
|
6e58c12752 | ||
|
|
f332379ea0 | ||
|
|
190a702225 | ||
|
|
191f04f7dc | ||
|
|
727275a027 | ||
|
|
d81506de1e | ||
|
|
881c1d63a1 | ||
|
|
a578617cc0 | ||
|
|
1aa22c1467 | ||
|
|
45c0003e53 | ||
|
|
56e4842db0 | ||
|
|
0e1d017993 | ||
|
|
5c5dc75641 | ||
|
|
baae5b4a06 | ||
|
|
0dfeb9e674 | ||
|
|
c53b36fe85 | ||
|
|
b8ea76ba72 | ||
|
|
d5d1932370 | ||
|
|
5956cea1d1 | ||
|
|
709e6b4497 | ||
|
|
e0e9e57a72 | ||
|
|
8a9285aacb | ||
|
|
46610792e9 | ||
|
|
7e213cfb50 | ||
|
|
a187ad8e9e | ||
|
|
ca9e309d30 | ||
|
|
5da8388fc6 | ||
|
|
bddcd9b095 | ||
|
|
66daa74232 | ||
|
|
8728bd87ed | ||
|
|
6a51e6893e | ||
|
|
416707b087 | ||
|
|
b34387745a | ||
|
|
e762ab8b54 | ||
|
|
f301a4ca19 | ||
|
|
0ec157d579 | ||
|
|
82480995b4 | ||
|
|
1058872a0b | ||
|
|
1f6f1669cf | ||
|
|
62172f6fb5 | ||
|
|
1482224c54 | ||
|
|
8e0ad48c21 | ||
|
|
ffc480c2e9 | ||
|
|
37ae232080 | ||
|
|
03bbe6c418 | ||
|
|
2a61122b5e | ||
|
|
0712b236c3 | ||
|
|
848f53c1d3 | ||
|
|
1a0e13f94e | ||
|
|
217b054cf5 | ||
|
|
3f90eff494 | ||
|
|
1db190cb66 | ||
|
|
31375d48ca | ||
|
|
4a56f2baab | ||
|
|
be1f4f7972 | ||
|
|
986ef4e69c | ||
|
|
6d2337d9e8 | ||
|
|
8f441c9f7a | ||
|
|
a27d5c51f1 | ||
|
|
b2d202cb5d | ||
|
|
b312bc0b4d | ||
|
|
194014678e | ||
|
|
89be7c0465 | ||
|
|
c99d8d0a08 | ||
|
|
43508ac476 | ||
|
|
46d3058341 | ||
|
|
e0d79ee032 | ||
|
|
90ead3cfb8 | ||
|
|
b2bed465e8 | ||
|
|
ac8b81c2b7 | ||
|
|
39ecca84d4 | ||
|
|
670cae8348 | ||
|
|
abeb5f3794 | ||
|
|
1d936c968a | ||
|
|
609c641323 | ||
|
|
bb3a89577c | ||
|
|
eec5f9fccc | ||
|
|
65470e5c7d | ||
|
|
bc18c184e5 | ||
|
|
eb164165f6 | ||
|
|
220b352b70 | ||
|
|
a48d77bdef | ||
|
|
bb0c89d944 | ||
|
|
e4441489bc | ||
|
|
647d46507d | ||
|
|
d96bb2868d | ||
|
|
5d7a3b80e9 | ||
|
|
350b1e8683 | ||
|
|
e2df287aad | ||
|
|
ed69feaaff | ||
|
|
06c30450ce | ||
|
|
587ce83e3f | ||
|
|
b990b167d4 | ||
|
|
3be7b9d75a | ||
|
|
170b76cdd1 | ||
|
|
2da7607ea6 | ||
|
|
5fae37271e | ||
|
|
74c17c7167 | ||
|
|
37412f505e | ||
|
|
6b6e005ce1 | ||
|
|
428a2078b6 | ||
|
|
54847a76da | ||
|
|
f2ae6a42a4 | ||
|
|
5669b34891 | ||
|
|
3d32dd05bb | ||
|
|
0e0c55aeca | ||
|
|
9dfa71f71c | ||
|
|
143e346dd5 | ||
|
|
56e989ccf7 | ||
|
|
06f4acee99 | ||
|
|
dfc93b35cc | ||
|
|
61299d69ad | ||
|
|
f51c6838ac | ||
|
|
307502d8b5 | ||
|
|
74c8015730 | ||
|
|
c916715a6c | ||
|
|
5ebf28c999 | ||
|
|
91adf3b8bb | ||
|
|
891d8dbedd | ||
|
|
7a4906fc75 | ||
|
|
e1a39e1dfc | ||
|
|
cbc363f671 | ||
|
|
88eb38f4ab | ||
|
|
e5e5df1966 | ||
|
|
e788001977 | ||
|
|
a082a3975f | ||
|
|
e71c23586a | ||
|
|
9c86e07067 | ||
|
|
55c62b663f | ||
|
|
48391fb862 | ||
|
|
b76d9b540a | ||
|
|
9d695340b4 | ||
|
|
cdaa04e460 | ||
|
|
0527fa677b | ||
|
|
7b1fc83e9b | ||
|
|
eecd021c04 | ||
|
|
5777e583cd | ||
|
|
b47aa1e9aa | ||
|
|
85d2688d62 | ||
|
|
578f286215 | ||
|
|
28e565aa83 | ||
|
|
d7baafb2eb | ||
|
|
0793782d31 | ||
|
|
7d3213741e | ||
|
|
9d8c3df93c | ||
|
|
3a32f5278d | ||
|
|
5e8df2b2b5 | ||
|
|
c26b682381 | ||
|
|
d34c834ea8 | ||
|
|
1eaa30756e | ||
|
|
c4d9dcacc9 | ||
|
|
ed6c505312 | ||
|
|
f2bcb7a1b8 | ||
|
|
20f8ead9ec | ||
|
|
899f7a43b1 | ||
|
|
2a5b8810bb | ||
|
|
ab91ec10b4 | ||
|
|
554f86bafa | ||
|
|
155c9421b9 | ||
|
|
8cce4557e0 | ||
|
|
99ce21a313 | ||
|
|
a281f241b5 | ||
|
|
e8d2bc8d8b | ||
|
|
e0524e813a | ||
|
|
24b44b686e | ||
|
|
690bd8a878 | ||
|
|
90424e7c20 | ||
|
|
eaebea55a4 | ||
|
|
0336454503 | ||
|
|
16afe18142 | ||
|
|
fbf275da19 | ||
|
|
1e5f9a72b0 | ||
|
|
e5db28a4bf | ||
|
|
d324c6776b | ||
|
|
ead03afeba | ||
|
|
e503fd574b | ||
|
|
3dc1754e50 | ||
|
|
0d9799de04 | ||
|
|
1b0e189e35 | ||
|
|
8e53db927a | ||
|
|
e74bfe2c75 | ||
|
|
14e7caf6b2 | ||
|
|
cde221b858 | ||
|
|
f33e7def06 | ||
|
|
10cd68e0f0 | ||
|
|
f3bdb28e57 | ||
|
|
23634d8de7 | ||
|
|
cfc981df2a | ||
|
|
9e1c0ffef4 | ||
|
|
78378400b9 | ||
|
|
ebf9b232b0 | ||
|
|
7136e24f8a | ||
|
|
eb3562f3c0 | ||
|
|
238aa92948 | ||
|
|
faeab50e71 | ||
|
|
6cbec2d0aa | ||
|
|
f606314f0c | ||
|
|
1d281273b1 | ||
|
|
dab764d019 | ||
|
|
f6f8bcd2a5 | ||
|
|
e9ae247cb1 | ||
|
|
4b3dde0b11 | ||
|
|
68bf7189e0 | ||
|
|
ef79a4d8c8 | ||
|
|
25337787e7 | ||
|
|
c68ec38e3f | ||
|
|
6448da507e | ||
|
|
c6c8130db4 | ||
|
|
477c8e6f42 | ||
|
|
ce185b2b48 | ||
|
|
87d5a54ba0 | ||
|
|
8f093ea93a | ||
|
|
4c641c1f2a | ||
|
|
ae38d3a87f | ||
|
|
44917600b6 | ||
|
|
c5090d91a1 | ||
|
|
e32b4a9a81 | ||
|
|
0fe4128ee6 | ||
|
|
af76c25f77 | ||
|
|
caad9b987c | ||
|
|
b5aba2624b | ||
|
|
f397e32638 | ||
|
|
18b8095a8d | ||
|
|
3f7a72e967 | ||
|
|
fb96d3f84d | ||
|
|
3ec32f9975 | ||
|
|
62d99ee3fc | ||
|
|
ad4ab16559 | ||
|
|
1bf5868e33 | ||
|
|
f1a922f3b3 | ||
|
|
274e786be9 | ||
|
|
6688f1c1eb | ||
|
|
1f84142915 | ||
|
|
f4d5705e4a | ||
|
|
f4cf8fe51c | ||
|
|
a83533d97d | ||
|
|
b372b8a3be | ||
|
|
3b89b71680 | ||
|
|
0c7ded471f | ||
|
|
0b51cde162 | ||
|
|
23baa40d9d | ||
|
|
3e183c2f5a | ||
|
|
29309f5913 | ||
|
|
48ceff86de | ||
|
|
45d6746219 | ||
|
|
edf5ea7974 | ||
|
|
b62d02f38f | ||
|
|
0593b330d8 | ||
|
|
58b6e97a9e | ||
|
|
edca359022 | ||
|
|
5a7ed86fba | ||
|
|
9cdb5251b6 | ||
|
|
3c1e5fcf16 | ||
|
|
3732cf72d6 | ||
|
|
a026154c6f | ||
|
|
a43d0b95c4 | ||
|
|
e9bf727253 | ||
|
|
57cd14f194 | ||
|
|
4f393a5f9f | ||
|
|
b7bbf1beb8 | ||
|
|
d2da05aa1b | ||
|
|
c9015a7e58 | ||
|
|
3a091d5def | ||
|
|
5f88f2cca7 | ||
|
|
2f30d235c2 | ||
|
|
10b2e1e7c5 | ||
|
|
b3ce696f36 | ||
|
|
212d20c80e | ||
|
|
1882c66bda | ||
|
|
8abe637468 | ||
|
|
db90ccc199 | ||
|
|
726abe8a32 | ||
|
|
8e0fe8a9a3 | ||
|
|
fbe54952f0 | ||
|
|
9a780cf22b | ||
|
|
f1f1678e13 | ||
|
|
e101219ad7 | ||
|
|
fd5945e533 | ||
|
|
1b96f6a9b3 | ||
|
|
f19a8044c3 | ||
|
|
2c9b3f8459 | ||
|
|
5538ecd7cc | ||
|
|
c643845100 | ||
|
|
3d392c6e05 | ||
|
|
80d419124e | ||
|
|
602d280aa3 | ||
|
|
ccb09d9f5f | ||
|
|
2e1da29fc1 | ||
|
|
4504a1a4bf | ||
|
|
98e10715ff | ||
|
|
eefaf55b1b | ||
|
|
f741643d75 | ||
|
|
88bd05020c | ||
|
|
20a39fbbab | ||
|
|
9e788adf56 | ||
|
|
5450f9a904 | ||
|
|
79e28694ef | ||
|
|
39eea79d8d | ||
|
|
98f943f2a5 | ||
|
|
51e77b9a96 | ||
|
|
7a799ebb2c | ||
|
|
b2bc1f6927 | ||
|
|
a8166a86ed | ||
|
|
debea9b761 | ||
|
|
7909308285 | ||
|
|
a74114fe34 | ||
|
|
119cee142e | ||
|
|
946eb84182 | ||
|
|
45bba0e190 | ||
|
|
f84b8530c5 | ||
|
|
eccf1c569c | ||
|
|
7ad96661ef | ||
|
|
8736e4a37e | ||
|
|
e8a2cfa7dc | ||
|
|
f06a1d8b00 | ||
|
|
b4472167c2 | ||
|
|
d22f1c18cc | ||
|
|
dcca8653a5 | ||
|
|
5575995541 | ||
|
|
6f266a30ff | ||
|
|
8f134c0bea | ||
|
|
44126d85ee | ||
|
|
2a41a72b8c | ||
|
|
45d2e6dff0 | ||
|
|
4e1afcd662 | ||
|
|
e668c7e725 | ||
|
|
9e5a852ee0 | ||
|
|
80b52a597f | ||
|
|
d355cb2b16 | ||
|
|
4ce27b5e60 | ||
|
|
62449968fa | ||
|
|
b7e12ec04e | ||
|
|
047bfc47c6 | ||
|
|
913e16ce20 | ||
|
|
3e602b58a2 | ||
|
|
6b341b1e90 | ||
|
|
e751bc67eb | ||
|
|
92bd73c657 | ||
|
|
2b0bdef6f9 | ||
|
|
9750fd6819 | ||
|
|
e1b1d187f4 | ||
|
|
7052a0a2dd | ||
|
|
962c820fba | ||
|
|
363eab25f0 | ||
|
|
4758641b1d | ||
|
|
f5a7404c7a | ||
|
|
618bafc238 | ||
|
|
355ad6a9e0 | ||
|
|
d59a090933 | ||
|
|
0e6fe5e728 | ||
|
|
f93cf255d4 | ||
|
|
6761cf2d7e | ||
|
|
79157cbad8 | ||
|
|
b8c67c320c | ||
|
|
e0d66b4be1 | ||
|
|
868d7b34ea | ||
|
|
30e62bc3bd | ||
|
|
a630fba34b | ||
|
|
92cb9d7785 | ||
|
|
0f31dc5c2c | ||
|
|
2a6164cc4a | ||
|
|
53763ae6ee | ||
|
|
a850520981 | ||
|
|
c0e4ccd032 | ||
|
|
f2e8294bdb | ||
|
|
e2f1fcca0e | ||
|
|
aaaaf21b6f | ||
|
|
9a9c9231db | ||
|
|
292f59f43d | ||
|
|
585b6f00f5 | ||
|
|
abb879fd4f | ||
|
|
f7c2a54212 | ||
|
|
c628caf174 | ||
|
|
6938bab429 | ||
|
|
0c9f641408 | ||
|
|
19f08785f0 | ||
|
|
535f54076c | ||
|
|
445e97ba7c | ||
|
|
d12d300c98 | ||
|
|
32f641b207 | ||
|
|
9724147344 | ||
|
|
dce030ffb8 | ||
|
|
1654f42194 | ||
|
|
3ff3cd9c78 | ||
|
|
3a0160beb0 | ||
|
|
d594243fbb | ||
|
|
02916e9cb2 | ||
|
|
1fdaf69376 | ||
|
|
2fa4234fc7 | ||
|
|
3b6ccf642c | ||
|
|
126fbe57bc | ||
|
|
6c3d4ebf6e | ||
|
|
eb366c255c | ||
|
|
6c4545544f | ||
|
|
d8e54618fe | ||
|
|
adf7378d73 | ||
|
|
624d57c08c | ||
|
|
06eb4e4d76 | ||
|
|
497e90751b | ||
|
|
a757b458ff | ||
|
|
387da46d73 | ||
|
|
b17a17c93d | ||
|
|
1ff0b37134 | ||
|
|
63a96706b1 | ||
|
|
a97399dd0a | ||
|
|
f2476d3ce8 | ||
|
|
fc832e4648 | ||
|
|
7d02af944f | ||
|
|
82b5983301 | ||
|
|
234af5cf67 | ||
|
|
09c752f00f | ||
|
|
5b4082d007 | ||
|
|
cdc8c1e25b | ||
|
|
4bec156db1 | ||
|
|
33f85e93a1 | ||
|
|
6be18d45e1 | ||
|
|
7e2b522a15 | ||
|
|
d7e2bd6fe1 | ||
|
|
4ad2697cc4 | ||
|
|
5bb28a0a7f | ||
|
|
4b85dc66d4 | ||
|
|
049f9a7f6b | ||
|
|
117bc66c6f | ||
|
|
26bbee8c86 | ||
|
|
ab9fad7943 | ||
|
|
7903557988 | ||
|
|
0e0101043b | ||
|
|
fb582ce72f | ||
|
|
679a29da7e | ||
|
|
d7c9550b7f | ||
|
|
e385338ee8 | ||
|
|
2b6312b337 | ||
|
|
ecfcaed0b5 | ||
|
|
f20c688a18 | ||
|
|
7687ae4dbd | ||
|
|
4624e9fca1 | ||
|
|
009e09fd58 | ||
|
|
a5bf83d2e7 | ||
|
|
4bcbe13689 | ||
|
|
049b08481a | ||
|
|
02b200c9aa | ||
|
|
234e8fa7b1 | ||
|
|
c4539fc4f9 | ||
|
|
9dd720a285 | ||
|
|
1c1e0b0c68 | ||
|
|
adb83f7796 | ||
|
|
28a02dc83e | ||
|
|
e318bb9b06 | ||
|
|
05388f748d | ||
|
|
e481437ab9 | ||
|
|
6becc82e26 | ||
|
|
c6847011e8 | ||
|
|
065aae682c | ||
|
|
33c33a32a2 | ||
|
|
cd551ef728 | ||
|
|
fa986b1d73 | ||
|
|
4616fe71e7 | ||
|
|
537b8cd90b | ||
|
|
d4b6d1549b | ||
|
|
f4a84efb46 | ||
|
|
2a991a3ce9 |
34
.builds/alpine-edge.yml
Normal file
34
.builds/alpine-edge.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
image: alpine/latest
|
||||
# apk add --update alpine-sdk
|
||||
packages:
|
||||
- cmd:setcap
|
||||
- autoconf
|
||||
- automake
|
||||
- byacc
|
||||
- expect
|
||||
- gettext
|
||||
- gettext-dev
|
||||
- gettext-lang
|
||||
- libbsd-dev
|
||||
- libcap-dev
|
||||
- libtool
|
||||
- linux-pam-dev
|
||||
- pkgconf
|
||||
- sed
|
||||
sources:
|
||||
- https://github.com/shadow-maint/shadow
|
||||
tasks:
|
||||
- build: |
|
||||
cd shadow
|
||||
./autogen.sh --without-selinux --disable-man --disable-nls
|
||||
grep ENABLE_ config.status
|
||||
- tasks: |
|
||||
cd shadow
|
||||
cat /proc/self/uid_map
|
||||
cat /proc/self/status
|
||||
make
|
||||
make DESTDIR=/tmp/shadow-inst install
|
||||
sudo make install
|
||||
#TODO - fix up the tests. Let's merge what's here now as it
|
||||
#at least tests build.
|
||||
#(cd tests; sudo ./run_some || { cat testsuite.log; false; })
|
||||
33
.builds/fedora.yml
Normal file
33
.builds/fedora.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
image: fedora/latest
|
||||
packages:
|
||||
- autoconf
|
||||
- automake
|
||||
- byacc
|
||||
- expect
|
||||
- findutils
|
||||
- gettext
|
||||
- gettext-devel
|
||||
- git
|
||||
- libbsd-devel
|
||||
- libselinux-devel
|
||||
- libsemanage-devel
|
||||
- libtool
|
||||
- libxslt
|
||||
- pkgconf
|
||||
sources:
|
||||
- https://github.com/shadow-maint/shadow
|
||||
tasks:
|
||||
- build: |
|
||||
cd shadow
|
||||
./autogen.sh --with-selinux --enable-man
|
||||
grep ENABLE_ config.status
|
||||
- tasks: |
|
||||
cd shadow
|
||||
cat /proc/self/uid_map
|
||||
cat /proc/self/status
|
||||
make
|
||||
make DESTDIR=/tmp/shadow-inst install
|
||||
sudo make install
|
||||
#TODO - fix up the tests. Let's merge what's here now as it
|
||||
#at least tests build.
|
||||
#(cd tests; sudo ./run_some || { cat testsuite.log; false; })
|
||||
28
.builds/ubuntu-focal.yml
Normal file
28
.builds/ubuntu-focal.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
image: ubuntu/focal
|
||||
packages:
|
||||
- automake
|
||||
- autopoint
|
||||
- xsltproc
|
||||
- libbsd-dev
|
||||
- libselinux1-dev
|
||||
- gettext
|
||||
- expect
|
||||
- byacc
|
||||
- libtool
|
||||
- pkgconf
|
||||
sources:
|
||||
- https://github.com/shadow-maint/shadow
|
||||
tasks:
|
||||
- build: |
|
||||
cd shadow
|
||||
./autogen.sh --without-selinux --disable-man
|
||||
grep ENABLE_ config.status
|
||||
- tasks: |
|
||||
cd shadow
|
||||
cat /proc/self/uid_map
|
||||
cat /proc/self/status
|
||||
systemd-detect-virt
|
||||
make
|
||||
make DESTDIR=/tmp/shadow-inst install
|
||||
sudo make install
|
||||
(cd tests; sudo ./run_some || { cat testsuite.log; false; })
|
||||
28
.builds/ubuntu-jammy.yml
Normal file
28
.builds/ubuntu-jammy.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
image: ubuntu/22.04
|
||||
packages:
|
||||
- automake
|
||||
- autopoint
|
||||
- xsltproc
|
||||
- libbsd-dev
|
||||
- libselinux1-dev
|
||||
- gettext
|
||||
- expect
|
||||
- byacc
|
||||
- libtool
|
||||
- pkgconf
|
||||
sources:
|
||||
- https://github.com/shadow-maint/shadow
|
||||
tasks:
|
||||
- build: |
|
||||
cd shadow
|
||||
./autogen.sh --without-selinux --enable-man
|
||||
grep ENABLE_ config.status
|
||||
- tasks: |
|
||||
cat /proc/self/uid_map
|
||||
cat /proc/self/status
|
||||
systemd-detect-virt
|
||||
cd shadow
|
||||
make
|
||||
make DESTDIR=/tmp/shadow-inst install
|
||||
sudo make install
|
||||
(cd tests; sudo ./run_some || { cat testsuite.log; false; })
|
||||
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*.{c,h}]
|
||||
indent_style = tab
|
||||
12
.github/actions/install-dependencies/action.yml
vendored
Normal file
12
.github/actions/install-dependencies/action.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: 'Install dependencies'
|
||||
description: 'Install dependencies to build shadow-utils'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y ubuntu-dev-tools libbsd-dev
|
||||
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
|
||||
sudo apt-get update -y
|
||||
sudo apt-get -y build-dep shadow
|
||||
108
.github/workflows/runner.yml
vendored
Normal file
108
.github/workflows/runner.yml
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: debug
|
||||
run: |
|
||||
id
|
||||
which bash
|
||||
whoami
|
||||
env
|
||||
ps -ef
|
||||
pwd
|
||||
cat /proc/self/uid_map
|
||||
cat /proc/self/status
|
||||
systemd-detect-virt
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo cat /etc/apt/sources.list
|
||||
sudo sed -i '/deb-src/d' /etc/apt/sources.list
|
||||
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
|
||||
export DEBIAN_PRIORITY=critical
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
# let's try to work around upgrade breakage in a pkg we don't care about
|
||||
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
|
||||
sudo apt-get update
|
||||
sudo apt-get -y dist-upgrade
|
||||
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf
|
||||
sudo apt-get -y build-dep shadow
|
||||
- name: configure
|
||||
run: |
|
||||
autoreconf -v -f --install
|
||||
./autogen.sh --without-selinux --disable-man --with-yescrypt
|
||||
- run: make
|
||||
- run: make install DESTDIR=${HOME}/rootfs
|
||||
- run: sudo make install
|
||||
- name: run tests in shell with tty
|
||||
shell: 'script -q -e -c "bash {0}"'
|
||||
run: |
|
||||
set -e
|
||||
cd tests
|
||||
sudo ./run_some
|
||||
cat testsuite.log
|
||||
|
||||
# Make sure that 'make dist' makes a usable tarball with no missing files
|
||||
dist-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo cat /etc/apt/sources.list
|
||||
sudo sed -i '/deb-src/d' /etc/apt/sources.list
|
||||
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
|
||||
export DEBIAN_PRIORITY=critical
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
# let's try to work around upgrade breakage in a pkg we don't care about
|
||||
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
|
||||
sudo apt-get update
|
||||
sudo apt-get -y dist-upgrade
|
||||
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf
|
||||
sudo apt-get -y build-dep shadow
|
||||
|
||||
- name: Test make dist
|
||||
run: |
|
||||
./autogen.sh
|
||||
make dist
|
||||
f=shadow-*.tar.gz
|
||||
tar -zxf $f
|
||||
d=$(basename $f .tar.gz)
|
||||
cd $d
|
||||
./configure
|
||||
make -j5
|
||||
|
||||
container-build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [alpine, debian, fedora]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build container
|
||||
run: |
|
||||
docker buildx build -f ./share/containers/${{ matrix.os }}.dockerfile . --output build-out
|
||||
|
||||
- name: Store artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.os }}-build
|
||||
path: |
|
||||
./build-out/config.log
|
||||
./build-out/config.h
|
||||
if-no-files-found: ignore
|
||||
61
.github/workflows/static-code-analysis.yml
vendored
Normal file
61
.github/workflows/static-code-analysis.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: "Static code analysis"
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
schedule:
|
||||
# Everyday at midnight
|
||||
- cron: '0 0 * * *'
|
||||
jobs:
|
||||
codeql:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
id: dependencies
|
||||
uses: ./.github/actions/install-dependencies
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: cpp
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Configure shadow-utils
|
||||
run: ./autogen.sh --without-selinux --disable-man
|
||||
|
||||
- name: Build shadow-utils
|
||||
run: |
|
||||
PROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
|
||||
make -kj$PROCESSORS || true
|
||||
|
||||
- name: Check build errors
|
||||
run: make
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
differential-shellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Doc: https://github.com/redhat-plumbers-in-action/differential-shellcheck#usage
|
||||
- name: Differential ShellCheck
|
||||
uses: redhat-plumbers-in-action/differential-shellcheck@v3
|
||||
with:
|
||||
severity: warning
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -47,4 +47,5 @@ Makefile.in
|
||||
|
||||
/shadow.spec
|
||||
/shadow-*.tar.*
|
||||
/libmisc/getdate.c
|
||||
/lib/getdate.c
|
||||
/libsubid/subid.h
|
||||
|
||||
@@ -36,7 +36,7 @@ addons:
|
||||
notification_email: christian.brauner@ubuntu.com,serge@hallyn.com
|
||||
|
||||
build_command_prepend: "./autogen.sh --without-selinux --disable-man"
|
||||
build_command: "make -j4"
|
||||
build_command: "make -kj4 || make"
|
||||
branch_pattern: master
|
||||
|
||||
script:
|
||||
|
||||
90
AUTHORS.md
Normal file
90
AUTHORS.md
Normal file
@@ -0,0 +1,90 @@
|
||||
Thanks to at least the following people for sending patches, bug
|
||||
reports and various comments. This list may be incomplete, I received
|
||||
a lot of mail...
|
||||
|
||||
# Maintainers
|
||||
* Marek Michałkiewicz <marekm72@gmail.com> (1995-2000)
|
||||
* Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
|
||||
* Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
|
||||
* Serge E. Hallyn <serge@hallyn.com> (2014-now)
|
||||
* Christian Brauner <christian@brauner.io> (2019-now)
|
||||
* Iker Pedrosa <ipedrosa@redhat.com> (2022-now)
|
||||
|
||||
# Authors and contributors
|
||||
* Adam Rudnicki <adam@v-lo.krakow.pl>
|
||||
* Alan Curry <pacman@tardis.mars.net>
|
||||
* Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Alexander O. Yuriev <alex@bach.cis.temple.edu>
|
||||
* Algis Rudys <arudys@rice.edu>
|
||||
* Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
* Andy Zaugg <andy.zaugg@gmail.com>
|
||||
* Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
|
||||
* Anton Gluck <gluc@midway.uchicago.edu>
|
||||
* Arkadiusz Miskiewicz <misiek@pld.org.pl>
|
||||
* Ben Collins <bcollins@debian.org>
|
||||
* Brian R. Gaeke <brg@dgate.org>
|
||||
* Calle Karlsson <ckn@kash.se>
|
||||
* Chip Rosenthal <chip@unicom.com>
|
||||
* Chris Evans <lady0110@sable.ox.ac.uk>
|
||||
* Chris Lamb <chris@chris-lamb.co.uk>
|
||||
* Cristian Gafton <gafton@sorosis.ro>
|
||||
* Dan Walsh <dwalsh@redhat.com>
|
||||
* Darcy Boese <possum@chardonnay.niagara.com>
|
||||
* Dave Hagewood <admin@arrowweb.com>
|
||||
* David A. Holland <dholland@hcs.harvard.edu>
|
||||
* David Frey <David.Frey@lugs.ch>
|
||||
* Ed Carp <ecarp@netcom.com>
|
||||
* Ed Neville <ed@s5h.net>
|
||||
* Eric W. Biederman" <ebiederm@xmission.com>
|
||||
* Floody <flood@evcom.net>
|
||||
* Frank Denis <j@4u.net>
|
||||
* George Kraft IV <gk4@us.ibm.com>
|
||||
* Greg Mortensen <loki@world.std.com>
|
||||
* Guido van Rooij
|
||||
* Guy Maor <maor@debian.org>
|
||||
* Hrvoje Dogan <hdogan@bjesomar.srce.hr>
|
||||
* Jakub Hrozek <jhrozek@redhat.com>
|
||||
* Janos Farkas <chexum@bankinf.banki.hu>
|
||||
* Jason Franklin <jason.franklin@quoininc.com>
|
||||
* Jay Soffian <jay@lw.net>
|
||||
* Jesse Thilo <Jesse.Thilo@pobox.com>
|
||||
* Joey Hess <joey@kite.ml.org>
|
||||
* John Adelsberger <jja@umr.edu>
|
||||
* Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
|
||||
* Jon Lewis <jlewis@lewis.org>
|
||||
* Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
|
||||
* Judd Bourgeois <shagboy@bluesky.net>
|
||||
* Juergen Heinzl <unicorn@noris.net>
|
||||
* Juha Virtanen <jiivee@iki.fi>
|
||||
* Julian Pidancet <julian.pidancet@gmail.com>
|
||||
* Julianne Frances Haugh <julie78787@gmail.com>
|
||||
* Leonard N. Zubkoff <lnz@dandelion.com>
|
||||
* Luca Berra <bluca@www.polimi.it>
|
||||
* Lukáš Kuklínek <lkukline@redhat.com>
|
||||
* Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
|
||||
* Marc Ewing <marc@redhat.com>
|
||||
* Martin Bene <mb@sime.com>
|
||||
* Martin Mares <mj@gts.cz>
|
||||
* Michael Meskes <meskes@topsystem.de>
|
||||
* Michael Talbot-Wilson <mike@calypso.bns.com.au>
|
||||
* Michael Vetter <jubalh@iodoru.org>
|
||||
* Mike Frysinger <vapier@gentoo.org>
|
||||
* Mike Pakovic <mpakovic@users.southeast.net>
|
||||
* Nicolas François <nicolas.francois@centraliens.net>
|
||||
* Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
|
||||
* Pavel Machek <pavel@bug.ucw.cz>
|
||||
* Peter Vrabec <pvrabec@redhat.com>
|
||||
* Phillip Street
|
||||
* Rafał Maszkowski <rzm@icm.edu.pl>
|
||||
* Rani Chouha <ranibey@smartec.com>
|
||||
* Sami Kerola <kerolasa@rocketmail.com>
|
||||
* Scott Garman <scott.a.garman@intel.com>
|
||||
* Sebastian Rick Rijkers <srrijkers@gmail.com>
|
||||
* Seraphim Mellos <mellos@ceid.upatras.gr>
|
||||
* Shane Watts <shane@nexus.mlckew.edu.au>
|
||||
* Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
|
||||
* Thorsten Kukuk <kukuk@suse.de>
|
||||
* Tim Hockin <thockin@eagle.ais.net>
|
||||
* Timo Karjalainen <timok@iki.fi>
|
||||
* Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
|
||||
* Werner Fink <werner@suse.de>
|
||||
143
COPYING
143
COPYING
@@ -1,118 +1,41 @@
|
||||
NOTE:
|
||||
This license has been obsoleted by the change to the BSD-style copyright.
|
||||
You may continue to use this license if you wish, but you are under no
|
||||
obligation to do so.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
(*
|
||||
This document is freely plagiarised from the 'Artistic Licence',
|
||||
distributed as part of the Perl v4.0 kit by Larry Wall, which is
|
||||
available from most major archive sites. I stole it from CrackLib.
|
||||
All files under this project either
|
||||
|
||||
$Id$
|
||||
*)
|
||||
1. fall under the BSD 3 clause license (by default).
|
||||
|
||||
This documents purpose is to state the conditions under which this
|
||||
Package (See definition below) viz: "Shadow", the Shadow Password Suite
|
||||
which is held by Julianne Frances Haugh, may be copied, such that the
|
||||
copyright holder maintains some semblance of artistic control over the
|
||||
development of the package, while giving the users of the package the
|
||||
right to use and distribute the Package in a more-or-less customary
|
||||
fashion, plus the right to make reasonable modifications.
|
||||
2. carry an SPDX header declaring what license applies.
|
||||
|
||||
So there.
|
||||
or
|
||||
|
||||
***************************************************************************
|
||||
3. list a full custom license
|
||||
|
||||
Definitions:
|
||||
This software is originally
|
||||
|
||||
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
|
||||
|
||||
A "Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files created
|
||||
through textual modification, or segments thereof.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been modified,
|
||||
or has been modified in accordance with the wishes of the Copyright
|
||||
Holder.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or copyrights
|
||||
for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing this
|
||||
Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the basis of
|
||||
media cost, duplication charges, time of people involved, and so on.
|
||||
(You will not be required to justify it to the Copyright Holder, but
|
||||
only to the computing community at large as a market that must bear the
|
||||
fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item itself,
|
||||
though there may be fees involved in handling the item. It also means
|
||||
that recipients of the item may redistribute it under the same
|
||||
conditions they received it.
|
||||
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated
|
||||
disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way,
|
||||
provided that you insert a prominent notice in each changed file stating
|
||||
how and when AND WHY you changed that file, and provided that you do at
|
||||
least ONE of the following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or an
|
||||
equivalent medium, or placing the modifications on a major archive site
|
||||
such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict with
|
||||
standard executables, which must also be provided, and provide separate
|
||||
documentation for each non-standard executable that clearly documents
|
||||
how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of the
|
||||
Package with your modifications.
|
||||
|
||||
c) accompany any non-standard executables with their corresponding
|
||||
Standard Version executables, giving the non-standard executables
|
||||
non-standard names, and clearly documenting the differences in manual
|
||||
pages (or equivalent), together with instructions on where to get the
|
||||
Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this Package.
|
||||
YOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may
|
||||
distribute this Package in aggregate with other (possibly commercial)
|
||||
programs as part of a larger (possibly commercial) software distribution
|
||||
provided that YOU DO NOT ADVERTISE this package as a product of your
|
||||
own.
|
||||
|
||||
6. The name of the Copyright Holder may not be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
|
||||
202
ChangeLog
202
ChangeLog
@@ -1,3 +1,161 @@
|
||||
2022-11-08 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* useradd.8: fix default group ID (Tim Biermann)
|
||||
* Revert drop of subid_init() (Serge Hallyn)
|
||||
* Georgian translation (NorwayFun)
|
||||
* useradd: Avoid taking unneeded space: do not reset non-existent data
|
||||
in lastlog (David Kalnischkies)
|
||||
* relax username restrictions (Alexander Kanavin)
|
||||
* selinux: check MLS enabled before setting serange (genBTC)
|
||||
* copy_tree: use fchmodat instead of chmod (Samanta Navarro)
|
||||
* copy_tree: don't block on FIFOs (Samanta Navarro)
|
||||
* add shell linter (Jan Macku)
|
||||
* copy_tree: carefully treat permissions (Samanta Navarro)
|
||||
* lib/commonio: make lock failures more detailed (Luca BRUNO)
|
||||
* lib: use strzero and memzero where applicable (Christian Göttsche)
|
||||
* Update Dutch translation (Frans Spiesschaert)
|
||||
* Don't test for NULL before calling free (Alex Colomar)
|
||||
* Use libc MAX() and MIN() (Alejandro Colomar)
|
||||
* chage: Fix regression in print_date (Xiami)
|
||||
* usermod: report error if homedir does not exist (Iker Pedrosa)
|
||||
* libmisc: minimum id check for system accounts (Iker Pedrosa)
|
||||
* fix usermod -rG x y wrongly adding a group (xyz)
|
||||
* man: add missing space in useradd.8.xml (Iker Pedrosa)
|
||||
* lastlog: check for localtime() return value (Iker Pedrosa)
|
||||
* Raise limit for passwd and shadow entry length (Iker Pedrosa)
|
||||
* Remove adduser-old.c (Alejandro Colomar)
|
||||
* useradd: Fix buffer overflow when using a prefix (David Michael)
|
||||
* Don't warn when failed to open /etc/nsswitch.conf (Serge Hallyn)
|
||||
|
||||
2022-08-15 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Address CVE-2013-4235 (TOCTTOU when copying directories)
|
||||
(Christian Göttsche)
|
||||
|
||||
2022-08-15 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Fix uk manpages
|
||||
|
||||
2022-08-08 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Add absolute path hint to --root (Celeste Liu)
|
||||
* Various cleanups (Christian Göttsche)
|
||||
* Fix Ubuntu release used in CI tests (Jeremy Whiting)
|
||||
* add -F options to useradd (and tests) (Masatake YAMATO)
|
||||
* useradd manpage updates (Masatake YAMATO and Alexander Zhang))
|
||||
* Check for ownerid (not just username) in subid ranges (Iker Pedrosa)
|
||||
|
||||
2022-07-04 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Declare file local functions static (Christian Göttsche)
|
||||
* Use strict prototypes (Christian Göttsche)
|
||||
* Do not drop const qualifier for Basename (Christian Göttsche)
|
||||
* Constify various pointers (Christian Göttsche)
|
||||
* Don't return uninitialized memory (Christian Göttsche)
|
||||
* Don't let compiler optimize away memory cleaning (Christian Göttsche)
|
||||
* Remove many obsolete compatibility checks and defines (Alejandro Colomar)
|
||||
* Modify ID range check in useradd (Iker Pedrosa)
|
||||
* Use "extern "C"" to make libsubid easier to use from C++ (Alois Wohlschlager)
|
||||
* French translation updates (bubu)
|
||||
* Fix s/with-pam/with-libpam/ (serge)
|
||||
* Spanish translation updates (Fernando)
|
||||
* French translation fixes (Balint Reczey)
|
||||
* Default max group name length to 32 (Jami Kettunen)
|
||||
* Fix PAM service files without-selinux (Ali Riza KESKIN)
|
||||
* Improve manpages (Markus Hiereth)
|
||||
- groupadd, useradd, usermod
|
||||
- groups and id
|
||||
- pwck
|
||||
* Add fedora to CI builds (Iker Pedrosa)
|
||||
* Fix condition under which pw_dir check happens (Ed Neville)
|
||||
* logoutd: switch to strncat (Steve Grubb)
|
||||
* AUTHORS: improve markdown output (Iker Pedrosa)
|
||||
* Handle ERANGE errors correctly (Niko)
|
||||
* Check for fopen NULL return (juyin)
|
||||
* Split get_salt() into its own fn juyin)
|
||||
* Get salt before chroot to ensure /dev/urandom. (juyin)
|
||||
* Chpasswd code cleanup (juyin)
|
||||
* Work around git safe.directory enforcement (serge)
|
||||
* Alphabetize order in usermod help (Matheus Marques)
|
||||
* Erase password copy on error branches (Christian Göttsche)
|
||||
* Suggest using --badname if needed (Iker Pedrosa)
|
||||
* Update translation files (Iker Pedrosa)
|
||||
* Correct badnames option to badname (Iker Pedrosa)
|
||||
* configure: replace obsolete autoconf macros (Christian Göttsche)
|
||||
* tests: replace egrep with grep -E (Sam James)
|
||||
* Update Ukrainian translations (Yuri Chornoivan)
|
||||
* Cleanups (Iker Pedrosa)
|
||||
- Remove redeclared variable
|
||||
- Remove commented out code and FIXMEs
|
||||
- Add header guards
|
||||
- Initialize local variables
|
||||
* CI updates (Iker Pedrosa)
|
||||
- Create github workflow to install dependencies
|
||||
- Enable CodeQL
|
||||
- Update actions version
|
||||
* libmisc: use /dev/urandom as fallback if other methods fail (Xi Ruoyao)
|
||||
|
||||
|
||||
2022-01-02 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* build: include lib/shadowlog_internal.h in dist tarballs (Sam James)
|
||||
|
||||
2022-01-02 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Handle possible TOCTTOU issues in usermod/userdel (edneville)
|
||||
* (CVE-2013-4235)
|
||||
* Use O_NOFOLLOW when copying file
|
||||
* Kill all user tasks in userdel
|
||||
* Fix useradd -D segfault (Xi Ruoyao)
|
||||
* Clean up obsolete libc feature-check ifdefs (Alejandro Colomar)
|
||||
* Fix -fno-common build breaks due to duplicate Prog declarations
|
||||
(Adam Sampson)
|
||||
* Have single date_to_str definition (Alejandro Colomar)
|
||||
* Fix libsubid SONAME version (Sam James)
|
||||
|
||||
2021-12-19 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
Note: From this release forward, su from this package should be
|
||||
considered deprecated. Please replace any users of it with su from
|
||||
util-linux. Please open an issue if there is a problem with that.
|
||||
We intend to remove it in an upcoming release.
|
||||
|
||||
* libsubid fixes (Xi Ruoyao, Serge Hallyn, Iker Pedrosa, Mike Gilbert,
|
||||
GalaxyMaster, and Luís Ferreira)
|
||||
* Rename the test program list_subid_ranges to getsubids, write
|
||||
a manpage, so distros can ship it. (Iker Pedrosa)
|
||||
* Add libeconf dep for new*idmap (Iker Pedrosa)
|
||||
* Allow all group types with usermod -G (Iker Pedrosa)
|
||||
* Avoid useradd generating empty subid range (Iker Pedrosa)
|
||||
* Handle NULL pw_passwd (Jaroslav Jindrak)
|
||||
* Fix default value SHA_get_salt_rounds (Mike Gilbert)
|
||||
* Use https where possible in README (Paul Menzel)
|
||||
* Update content and format of README (Iker Pedrosa)
|
||||
* Translation updates (Balint Reczey, Frans Spiesschaert)
|
||||
* Switch from xml2po to itstool in 'make dist' (Serge Hallyn)
|
||||
* Fix double frees (Michael Vetter)
|
||||
* Add LOG_INIT configurable to useradd (Andy Zaugg)
|
||||
* Add CREATE_MAIL_SPOOL documentation (Andy Zaugg)
|
||||
* Create a security.md
|
||||
* Fix su never being SIGKILLd when trapping TERM (Ruihan li)
|
||||
* Fix wrong SELinux labels in several possible cases (Iker Pedrosa)
|
||||
* Fix missing chmod in chadowtb_move (GalaxyMaster)
|
||||
* Handle malformed hushlogins entries (Tobias Stoeckmann)
|
||||
* Fix groupdel segv when passwd does not exist (François Rigault)
|
||||
* Fix covscan-found newgrp segfault (Iker Pedrosa)
|
||||
* Remove trailing slash on hoedir (Ed Neville)
|
||||
* Fix passwd -l message - it does not change expirey (Ed Neville)
|
||||
* Fix SIGCHLD handling bugs in su and vipw (Tobias Stoeckmann)
|
||||
* Remove special case for "" in usermod (Alejandro Colomar)
|
||||
* Implement usermod -rG to remove a specific group
|
||||
(Andy Zaugg)
|
||||
* call pam_end() after fork in child path for su and login
|
||||
(Björn Fischer)
|
||||
* useradd: In absence of /etc/passwd, assume 0 == root
|
||||
(Ludwig Nussel)
|
||||
* lib: check NULL before freeing data (Iker Pedrosa)
|
||||
* Fix pwck segfault (Iker Pedrosa)
|
||||
|
||||
2021-07-22 Serge Hallyn <serge@hallyn.com>
|
||||
|
||||
* Updated translations (Björn Esser, Juergen Hoetzel)
|
||||
@@ -285,7 +443,7 @@
|
||||
2013-08-15 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
* src/usermod.c: Check early if /etc/subuid (/etc/subgid) exists
|
||||
when option -v/-V (-w/-W) are provided.
|
||||
when option -v/-V (-w/-W) are provided.
|
||||
|
||||
2013-08-15 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
@@ -662,8 +820,8 @@
|
||||
|
||||
* configure.in: Prepare for next point release 4.2.
|
||||
* if using the static char* for pw_dir, strdup it so
|
||||
pw_free() can be used. (Closes: Debian#691459, alioth#313957)
|
||||
* Kill the child process group, rather than just the
|
||||
pw_free() can be used. (Closes: Debian#691459, alioth#313957)
|
||||
* Kill the child process group, rather than just the
|
||||
immediate child; this is needed now that su no
|
||||
longer starts a controlling terminal when not running an
|
||||
interactive shell (closes: Debian#713979)
|
||||
@@ -890,7 +1048,7 @@
|
||||
|
||||
* po/pt.po: Updated to 557t.
|
||||
|
||||
2012-01-19 Holger Wansing <linux@wansing-online.de>
|
||||
2012-01-19 Holger Wansing <linux@wansing-online.de>
|
||||
|
||||
* po/de.po: Updated to 557t.
|
||||
|
||||
@@ -1477,8 +1635,8 @@
|
||||
* NEWS, src/chpasswd.c: Create a shadow entry if the password is
|
||||
set to 'x' in passwd and there are no entry in shadow for the
|
||||
user.
|
||||
* NEWS, src/chgpasswd.c: Create a gshadow entry if the password is
|
||||
set to 'x' in group and there are no entry in gshadow for the
|
||||
* NEWS, src/chgpasswd.c: Create a gshadow entry if the password is
|
||||
set to 'x' in group and there are no entry in gshadow for the
|
||||
group.
|
||||
|
||||
2011-07-28 Nicolas François <nicolas.francois@centraliens.net>
|
||||
@@ -1550,7 +1708,7 @@
|
||||
2011-07-22 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Fail in case of
|
||||
invalid configuration.
|
||||
invalid configuration.
|
||||
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Updated
|
||||
comments.
|
||||
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Be more strict
|
||||
@@ -1787,7 +1945,7 @@
|
||||
man/login.defs.d/DEFAULT_HOME.xml,
|
||||
man/login.defs.d/LOGIN_RETRIES.xml,
|
||||
man/login.defs.d/MD5_CRYPT_ENAB.xml,
|
||||
man/login.defs.d/PORTTIME_CHECKS_ENAB.xml,
|
||||
man/login.defs.d/PORTTIME_CHECKS_ENAB.xml,
|
||||
man/login.defs.d/SHA_CRYPT_MIN_ROUNDS.xml:
|
||||
Fix typos
|
||||
* man/po/de.po: German translation of manpages completed
|
||||
@@ -1834,7 +1992,7 @@
|
||||
|
||||
2011-03-30 YunQiang Su <wzssyqa@gmail.com>
|
||||
|
||||
* man/po/zh_CN.po: convert Simplified Chinese translation
|
||||
* man/po/zh_CN.po: convert Simplified Chinese translation
|
||||
of manpages to gettext
|
||||
* po/zh_CN.po: Simplified Chinese translation completed
|
||||
|
||||
@@ -1973,7 +2131,7 @@
|
||||
boolean. safe_system last argument is a boolean.
|
||||
* libmisc/system.c: Check return value of dup2.
|
||||
* libmisc/system.c: Do not check *printf/*puts return value.
|
||||
* libmisc/system.c: Do not check execve return value.
|
||||
* libmisc/system.c: Do not check execve return value.
|
||||
* libmisc/salt.c: Do not check *printf/*puts return value.
|
||||
* libmisc/loginprompt.c: Do not check gethostname return value.
|
||||
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Do not check
|
||||
@@ -2126,7 +2284,7 @@
|
||||
2010-04-04 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
* src/useradd.c: spool is a constant string.
|
||||
* src/useradd.c: Set the new copy_tree's paramater 'copy_root' to false
|
||||
* src/useradd.c: Set the new copy_tree's paramater 'copy_root' to false
|
||||
|
||||
2010-04-04 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
@@ -4975,7 +5133,7 @@
|
||||
<sgrubb@redhat.com>
|
||||
* src/groupadd.c: Log to audit with type AUDIT_ADD_GROUP instead
|
||||
of AUDIT_USER_CHAUTHTOK.
|
||||
* src/groupdel.c: Log to audit with type AUDIT_DEL_GROUP instead
|
||||
* src/groupdel.c: Log to audit with type AUDIT_DEL_GROUP instead
|
||||
of AUDIT_USER_CHAUTHTOK.
|
||||
* src/useradd.c: Log to audit with type AUDIT_ADD_USER /
|
||||
AUDIT_ADD_GROUP / AUDIT_USYS_CONFIG instead of
|
||||
@@ -5231,7 +5389,7 @@
|
||||
* NEWS, src/gpasswd.c: Use getopt_long instead of getopt. Added
|
||||
support for long options --add (-a), --delete (-d),
|
||||
--remove-password (-r), --restrict (-R), --administrators (-A),
|
||||
and --members (-M)
|
||||
and --members (-M)
|
||||
* man/gpasswd.1.xml: Document the new long options.
|
||||
* src/gpasswd.c: The sgrp structure is only used if SHADOWGRP is
|
||||
defined.
|
||||
@@ -7420,7 +7578,7 @@
|
||||
to mimic useradd's behavior choices of UID and GID.
|
||||
* src/newusers.c: Reuse the generic find_new_uid() and
|
||||
find_new_gid() functions. This permits to respect the
|
||||
UID_MIN/UID_MAX and GID_MIN/GID_MAX variables, should
|
||||
UID_MIN/UID_MAX and GID_MIN/GID_MAX variables, should
|
||||
* src/newusers.c: Check if the user or group exist using the
|
||||
external databases (with the libc getpwnam/getgrnam functions).
|
||||
Refuse to update an user which exist in an external database but
|
||||
@@ -9217,7 +9375,7 @@
|
||||
Debian's patch 202_it_man_uses_gettext. Thanks to Giuseppe
|
||||
Sacco who contributed the Italian translation.
|
||||
* man/de/de.po: (nearly) complete German translation of man pages
|
||||
Imported from Debian's patch 203_de-man-update. Thanks to
|
||||
Imported from Debian's patch 203_de-man-update. Thanks to
|
||||
Simon Brandmair
|
||||
* src/usermod.c: Clarify the online help of usermod for "-a"
|
||||
Imported from Debian's patch 402-clarify_usermod_usage
|
||||
@@ -9400,7 +9558,7 @@
|
||||
* NEWS: release date corrected.
|
||||
|
||||
* NEWS, src/su.c:
|
||||
fixed set enviroment too early when using PAM, so move it to !USE_PAM
|
||||
fixed set environment too early when using PAM, so move it to !USE_PAM
|
||||
(patch submitted by Mike Frysinger <vapier@gentoo.org>).
|
||||
|
||||
2006-07-30 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||
@@ -10087,7 +10245,7 @@
|
||||
* NEWS: cleanups.
|
||||
|
||||
* autogen.sh:
|
||||
by default in development enviroment use CFLAGS="-O2 -Wall".
|
||||
by default in development environment use CFLAGS="-O2 -Wall".
|
||||
|
||||
* src/chgpasswd.c (main): remove two unused variables (newgr and now).
|
||||
|
||||
@@ -11496,7 +11654,7 @@
|
||||
in OPTIONS section). Describe -a and -k options.
|
||||
|
||||
* NEWS, src/su.c:
|
||||
fixed twice copy enviroment which causes auth problems (bug was introduced in 4.0.12;
|
||||
fixed twice copy environment which causes auth problems (bug was introduced in 4.0.12;
|
||||
fix by Nicolas François <nicolas.francois@centraliens.net>).
|
||||
|
||||
* src/passwd.c, po/ja.po, po/ko.po, po/nb.po, po/nl.po, po/nn.po, po/pl.po, po/pt.po, po/pt_BR.po, po/ro.po, po/ru.po, po/sk.po, po/sq.po, po/sv.po, po/tl.po, po/tr.po, po/uk.po, po/vi.po, po/zh_CN.po, po/zh_TW.po, po/bs.po, po/ca.po, po/cs.po, po/da.po, po/de.po, po/el.po, po/es.po, po/eu.po, po/fi.po, po/fr.po, po/he.po, po/id.po, po/it.po:
|
||||
@@ -12426,7 +12584,7 @@
|
||||
http://bugs.debian.org/48002
|
||||
|
||||
* src/login.c, NEWS:
|
||||
fixed loggin of username on succesful login (was using the normal username,
|
||||
fixed loggin of username on successful login (was using the normal username,
|
||||
when it should have used pam_user) http://bugs.debian.org/47819
|
||||
|
||||
2005-06-02 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||
@@ -12871,7 +13029,7 @@
|
||||
* man/pl/usermod.8: finish sync with english version.
|
||||
|
||||
* man/hu/login.1, man/pl/login.1, NEWS, man/Attic/login.1, man/de/login.1:
|
||||
removed fragment about abilities pass enviroment variables in login prompt.
|
||||
removed fragment about abilities pass environment variables in login prompt.
|
||||
|
||||
* man/Attic/gpasswd.1, man/Attic/newgrp.1:
|
||||
fixes by Nicolas Nicolas François <nicolas.francois@centraliens.net> (not all
|
||||
@@ -13350,7 +13508,7 @@
|
||||
removed not used translations.
|
||||
|
||||
* NEWS, src/su.c:
|
||||
fix adding of pam_env env variables to enviroment (Martin Schlemmer <azarah@nosferatu.za.org>).
|
||||
fix adding of pam_env env variables to environment (Martin Schlemmer <azarah@nosferatu.za.org>).
|
||||
|
||||
* NEWS, configure.in:
|
||||
fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables which was allways
|
||||
@@ -13447,7 +13605,7 @@
|
||||
|
||||
* NEWS, src/su.c:
|
||||
add pam_open_session() support. If builded without PAM support
|
||||
propagate $DISPLAY and $XAUTHORITY enviroment variables.
|
||||
propagate $DISPLAY and $XAUTHORITY environment variables.
|
||||
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
||||
|
||||
2004-10-23 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
EXTRA_DIST = NEWS README TODO shadow.spec.in
|
||||
|
||||
SUBDIRS = libmisc lib
|
||||
SUBDIRS = lib
|
||||
|
||||
if ENABLE_SUBIDS
|
||||
SUBDIRS += libsubid
|
||||
|
||||
38
NEWS
38
NEWS
@@ -15,7 +15,7 @@ shadow-4.1.5.1 -> shadow-4.2 UNRELEASED
|
||||
|
||||
- su
|
||||
* When su receives a signal (SIGTERM, or SIGINT/SIGQUIT in non
|
||||
interactive mode), kill the child process group, rather than just the
|
||||
interactive mode), kill the child process group, rather than just the
|
||||
immediate child.
|
||||
* Fix segmentation faults for users without a proper home or shell in
|
||||
their passwd entries.
|
||||
@@ -622,7 +622,7 @@ shadow-4.0.18.2 -> shadow-4.1.0 09-12-2007
|
||||
- Add support for uClibc with no l64a().
|
||||
- userdel, usermod: Fix infinite loop caused by erroneous group file
|
||||
containing two entries with the same name. (The fix strategy differs
|
||||
from
|
||||
from
|
||||
(https://bugzilla.redhat.com/show_bug.cgi?id=240915)
|
||||
- userdel: Abort if an error is detected while updating the passwd or group
|
||||
databases. The passwd or group files will not be written.
|
||||
@@ -696,7 +696,7 @@ shadow-4.0.18 -> shadow-4.0.18.1 03-08-2006
|
||||
shadow-4.0.17 -> shadow-4.0.18 01-08-2006
|
||||
|
||||
*** general:
|
||||
- su: fixed set enviroment too early when using PAM, so move it to !USE_PAM
|
||||
- su: fixed set environment too early when using PAM, so move it to !USE_PAM
|
||||
(patch submitted by Mike Frysinger <vapier@gentoo.org>),
|
||||
- groupadd, groupmod, useradd, usermod: fixed UID/GID overflow (fixed
|
||||
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920)
|
||||
@@ -855,7 +855,7 @@ shadow-4.0.14 -> shadow-4.0.15 13-03-2006
|
||||
- su: move exit() outside libmisc/shell.c::shell() for handle shell() errors
|
||||
on higher level (now is better visable where some programs exit with 126
|
||||
and 127 exit codes); added new shell() parameter (char *const envp[])
|
||||
which allow fix preserving enviroment in su on using -p, (patch by
|
||||
which allow fix preserving environment in su on using -p, (patch by
|
||||
Alexander Gattin <xrgtn@yandex.ru>),
|
||||
- su: added handle -c,--command option for GNU su compliance (merge
|
||||
437_su_-c_option Debian patch),
|
||||
@@ -966,7 +966,7 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
|
||||
to example described in ident(1) man page (modern compilers like latest GCC
|
||||
removes not used functions by global optimization).
|
||||
So "ident /usr/bin/passwd" will show again some useable informations
|
||||
- su: fixed twice copy enviroment which causes auth problems
|
||||
- su: fixed twice copy environment which causes auth problems
|
||||
(bug was introduced in 4.0.12; fix by Nicolas François <nicolas.francois@centraliens.net>),
|
||||
- chage: differentiate the different failure causes by the exit value
|
||||
This will permit to adduser Debian script to detect if chage failed because the
|
||||
@@ -1001,9 +1001,9 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
|
||||
shadow-4.0.11.1 -> shadow-4.0.12 22-08-2005
|
||||
|
||||
*** general:
|
||||
- newgrp, login: remove using login.defs::CLOSE_SESSIONS variable and always
|
||||
- newgrp, login: remove using login.defs::CLOSE_SESSIONS variable and always
|
||||
close PAM session,
|
||||
- fixed configure.in: really enable shadow group support by default (pointed by
|
||||
- fixed configure.in: really enable shadow group support by default (pointed by
|
||||
Greg Schafer <gschafer@zip.com.au> and Peter Vrabec <pvrabec@redhat.com>),
|
||||
- login.defs: removed handle QMAIL_DIR variable,
|
||||
- login: allow regular user to login on read-only root file system (not only for root)
|
||||
@@ -1080,7 +1080,7 @@ shadow-4.0.10 -> shadow-4.0.11 18-07-2005
|
||||
- S/Key support is back,
|
||||
- usermod: added -a option. This flag can only be used in conjunction with the -G
|
||||
option. It cause usermod to append user to the current supplementary group list.
|
||||
(patch by Peter Vrabec <pvrabec@redhat.com>)
|
||||
(patch by Peter Vrabec <pvrabec@redhat.com>)
|
||||
- chage: added missing \n in error messages,
|
||||
- useradd, groupadd: change -O option to -K and document it in man page,
|
||||
- su, sulogin, login: fixed erroneous warning messages when used with PAM about some
|
||||
@@ -1130,10 +1130,10 @@ shadow-4.0.9 -> shadow-4.0.10 28-06-2005
|
||||
http://bugs.debian.org/53570 http://bugs.debian.org/195048 http://bugs.debian.org/211884
|
||||
- login: made login's -f option also able to use the username after -- if none
|
||||
was passed as it's optarg
|
||||
http://bugs.debian.org/53702
|
||||
http://bugs.debian.org/53702
|
||||
- login: check for hushed login and pass PAM_SILENT if true,
|
||||
http://bugs.debian.org/48002
|
||||
- login: fixed username on succesful login (was using the normal username,
|
||||
- login: fixed username on successful login (was using the normal username,
|
||||
when it should have used pam_user) http://bugs.debian.org/47819
|
||||
- remove using SHADOWPWD #define so now shadow is always built with shadow
|
||||
password support,
|
||||
@@ -1208,11 +1208,11 @@ shadow-4.0.7 -> shadow-4.0.8 26-04-2005
|
||||
-- new: chage.1, chpasswd.8, expiry.1, faillog.5, faillog.8, getspnam.3,
|
||||
logoutd.8, porttime.5, pwck.8, shadow.3, shadowconfig.8, su.1,
|
||||
- passwd(1): fix #160477 Debian bug: improve -S output description,
|
||||
- newgrp(1): fix #251926, #166173, #113191 Debian bugs: explain why editing /etc/group
|
||||
- newgrp(1): fix #251926, #166173, #113191 Debian bugs: explain why editing /etc/group
|
||||
(without gshadow) doesn't permit to use newgrp,
|
||||
- newgrp(1): newgrp uses /bin/sh (not bash),
|
||||
- faillog(8): updated after rewritten faillog command for use getopt_long(),
|
||||
- login(1): removed fragment about abilities pass enviroment variables in login prompt,
|
||||
- login(1): removed fragment about abilities pass environment variables in login prompt,
|
||||
- gshadow(5): new file (by Nicolas Nicolas François <nicolas.francois@centraliens.net>),
|
||||
- usermod(8): fixed #302388 Debian bug: added separated -o option description,
|
||||
|
||||
@@ -1238,11 +1238,11 @@ shadow-4.0.6 -> shadow-4.0.7 26-01-2005
|
||||
- chpasswd:
|
||||
-- switch chpasswd to use getopt_long() and adds a --md5 option
|
||||
(by Ian Gulliver <ian@penguinhosting.net>),
|
||||
-- rewritten chpasswd(8) man page.
|
||||
-- rewritten chpasswd(8) man page.
|
||||
|
||||
shadow-4.0.5 -> shadow-4.0.6 08-11-2004
|
||||
|
||||
- su: fixed adding of pam_env env variables to enviroment
|
||||
- su: fixed adding of pam_env env variables to environment
|
||||
(Martin Schlemmer <azarah@nosferatu.za.org>),
|
||||
- autoconf: fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables
|
||||
which was always empty (Gregorio Guidi <g.guidi@sns.it>),
|
||||
@@ -1275,7 +1275,7 @@ shadow-4.0.4.1 -> shadow-4.0.5 27-10-2004
|
||||
including symlinks placed into /etc/skel/public_html for example.
|
||||
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=66819
|
||||
- su: add pam_open_session() support. If built without PAM support
|
||||
propagate $DISPLAY and $XAUTHORITY enviroment variables.
|
||||
propagate $DISPLAY and $XAUTHORITY environment variables.
|
||||
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
||||
- applied 036_pam_access_with_preauth.patch Debian patch submited by Bjorn
|
||||
Torkelsson <Bjorn.Torkelsson@hpc2n.umu.se>: add support for PAM account
|
||||
@@ -1309,7 +1309,7 @@ shadow-4.0.4 => shadow-4.0.4.1 14-01-2004
|
||||
- bug fixes in automake files for generate correct tar ball on "make dist":
|
||||
added missing "EXTRA_DIST = $(man_MANS)" in man/*/Makefile.am.
|
||||
|
||||
shadow-4.0.3 => shadow-4.0.4 14-01-2004
|
||||
shadow-4.0.3 => shadow-4.0.4 14-01-2004
|
||||
|
||||
*** general:
|
||||
- added missing information about -f options in groupadd usage message
|
||||
@@ -1408,7 +1408,7 @@ shadow-4.0.0 => shadow-4.0.1
|
||||
- fixes for handle/print correctly 32bit uid/gid (Thorsten Kukuk <kukuk@suse.de>),
|
||||
- implemented functions for better reloading the nscd cache (per NSS map)
|
||||
(Thorsten Kukuk <kukuk@suse.de>),
|
||||
- fixed warnings "not used but defined" on compile using gcc 3.0.x
|
||||
- fixed warnings "not used but defined" on compile using gcc 3.0.x
|
||||
(bulletpr00ph <bullet@users.sourceforge.net>),
|
||||
- added ja, ko translations found in SuSE,
|
||||
- added symlinks: newgrp -> sg, vipw -> vigr,
|
||||
@@ -1416,7 +1416,7 @@ shadow-4.0.0 => shadow-4.0.1
|
||||
- added sg(1) man page as roff .so link to newgrp(1),
|
||||
- installed fix for SEGV when using pwck -s on /etc/passwd file with
|
||||
empty lines in it.
|
||||
|
||||
|
||||
shadow-20001016 => shadow-4.0.0 06-01-2002
|
||||
|
||||
- fix bug discovered and fixed by Marcel Ritter
|
||||
@@ -1466,7 +1466,7 @@ shadow-20000902 => shadow-20001012
|
||||
overwrite previously existing groups in adduser,
|
||||
- added PAM support for chage (bind to "chage" PAM config file) also
|
||||
added PAM support for all other small tools like chpasswd, groupadd,
|
||||
groupdel, groupmod, newusers, useradd, userdel, usermod (bind to common
|
||||
groupdel, groupmod, newusers, useradd, userdel, usermod (bind to common
|
||||
"shadow" PAM config file) - this modifications mainly based on
|
||||
modifications prepared by Janek Rękojarski <baggins@pld.org.pl>,
|
||||
- many small fixes and improvements in automake (mow "make dist"
|
||||
|
||||
124
README
124
README
@@ -1,124 +0,0 @@
|
||||
Shadow SITES
|
||||
============
|
||||
|
||||
Homepage
|
||||
http://github.com/shadow-maint/shadow
|
||||
|
||||
Issue tracker
|
||||
http://github.com/shadow-maint/shadow/issues
|
||||
|
||||
Releases
|
||||
https://github.com/shadow-maint/shadow/releases
|
||||
|
||||
Mailing lists
|
||||
for general discuss: pkg-shadow-devel@alioth-lists.debian.net
|
||||
commit list: pkg-shadow-commits@alioth-lists.debian.net
|
||||
|
||||
Mailing lists subscription
|
||||
http://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-devel
|
||||
http://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-commits
|
||||
|
||||
Mailing lists archives:
|
||||
http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/
|
||||
http://alioth-lists.debian.net/pipermail/pkg-shadow-commits/
|
||||
|
||||
S/Key support:
|
||||
Shadow can be built with S/Key support using the S/Key package from:
|
||||
|
||||
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libskey/
|
||||
or
|
||||
http://gentoo.osuosl.org/distfiles/skey-1.1.5.tar.bz2
|
||||
|
||||
Authors and contributors
|
||||
========================
|
||||
|
||||
Thanks to at least the following people for sending patches, bug
|
||||
reports and various comments. This list may be incomplete, I received
|
||||
a lot of mail...
|
||||
|
||||
|
||||
Adam Rudnicki <adam@v-lo.krakow.pl>
|
||||
Alan Curry <pacman@tardis.mars.net>
|
||||
Aleksa Sarai <cyphar@cyphar.com>
|
||||
Alexander O. Yuriev <alex@bach.cis.temple.edu>
|
||||
Algis Rudys <arudys@rice.edu>
|
||||
Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
|
||||
Anton Gluck <gluc@midway.uchicago.edu>
|
||||
Arkadiusz Miskiewicz <misiek@pld.org.pl>
|
||||
Ben Collins <bcollins@debian.org>
|
||||
Brian R. Gaeke <brg@dgate.org>
|
||||
Calle Karlsson <ckn@kash.se>
|
||||
Chip Rosenthal <chip@unicom.com>
|
||||
Chris Evans <lady0110@sable.ox.ac.uk>
|
||||
Chris Lamb <chris@chris-lamb.co.uk>
|
||||
Cristian Gafton <gafton@sorosis.ro>
|
||||
Dan Walsh <dwalsh@redhat.com>
|
||||
Darcy Boese <possum@chardonnay.niagara.com>
|
||||
Dave Hagewood <admin@arrowweb.com>
|
||||
David A. Holland <dholland@hcs.harvard.edu>
|
||||
David Frey <David.Frey@lugs.ch>
|
||||
Ed Carp <ecarp@netcom.com>
|
||||
Ed Neville <ed@s5h.net>
|
||||
Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Floody <flood@evcom.net>
|
||||
Frank Denis <j@4u.net>
|
||||
George Kraft IV <gk4@us.ibm.com>
|
||||
Greg Mortensen <loki@world.std.com>
|
||||
Guido van Rooij
|
||||
Guy Maor <maor@debian.org>
|
||||
Hrvoje Dogan <hdogan@bjesomar.srce.hr>
|
||||
Jakub Hrozek <jhrozek@redhat.com>
|
||||
Janos Farkas <chexum@bankinf.banki.hu>
|
||||
Jason Franklin <jason.franklin@quoininc.com>
|
||||
Jay Soffian <jay@lw.net>
|
||||
Jesse Thilo <Jesse.Thilo@pobox.com>
|
||||
Joey Hess <joey@kite.ml.org>
|
||||
John Adelsberger <jja@umr.edu>
|
||||
Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
|
||||
Jon Lewis <jlewis@lewis.org>
|
||||
Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
|
||||
Judd Bourgeois <shagboy@bluesky.net>
|
||||
Juergen Heinzl <unicorn@noris.net>
|
||||
Juha Virtanen <jiivee@iki.fi>
|
||||
Julian Pidancet <julian.pidancet@gmail.com>
|
||||
Julianne Frances Haugh <jockgrrl@ix.netcom.com>
|
||||
Leonard N. Zubkoff <lnz@dandelion.com>
|
||||
Luca Berra <bluca@www.polimi.it>
|
||||
Lukáš Kuklínek <lkukline@redhat.com>
|
||||
Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
|
||||
Marc Ewing <marc@redhat.com>
|
||||
Martin Bene <mb@sime.com>
|
||||
Martin Mares <mj@gts.cz>
|
||||
Michael Meskes <meskes@topsystem.de>
|
||||
Michael Talbot-Wilson <mike@calypso.bns.com.au>
|
||||
Michael Vetter <jubalh@iodoru.org>
|
||||
Mike Frysinger <vapier@gentoo.org>
|
||||
Mike Pakovic <mpakovic@users.southeast.net>
|
||||
Nicolas François <nicolas.francois@centraliens.net>
|
||||
Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
|
||||
Pavel Machek <pavel@bug.ucw.cz>
|
||||
Peter Vrabec <pvrabec@redhat.com>
|
||||
Phillip Street
|
||||
Rafał Maszkowski <rzm@icm.edu.pl>
|
||||
Rani Chouha <ranibey@smartec.com>
|
||||
Sami Kerola <kerolasa@rocketmail.com>
|
||||
Scott Garman <scott.a.garman@intel.com>
|
||||
Sebastian Rick Rijkers <srrijkers@gmail.com>
|
||||
Seraphim Mellos <mellos@ceid.upatras.gr>
|
||||
Shane Watts <shane@nexus.mlckew.edu.au>
|
||||
Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
|
||||
Thorsten Kukuk <kukuk@suse.de>
|
||||
Tim Hockin <thockin@eagle.ais.net>
|
||||
Timo Karjalainen <timok@iki.fi>
|
||||
Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
|
||||
Werner Fink <werner@suse.de>
|
||||
|
||||
Maintainers
|
||||
===========
|
||||
|
||||
Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
|
||||
Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
|
||||
Serge E. Hallyn <serge@hallyn.com> (2014-now)
|
||||
Christian Brauner <christian@brauner.io> (2019-now)
|
||||
|
||||
41
README.md
Normal file
41
README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# shadow-utils
|
||||
|
||||
## Introduction
|
||||
The shadow-utils package includes the necessary programs for
|
||||
converting UNIX password files to the shadow password format, plus
|
||||
programs for managing user and group accounts. The pwconv command
|
||||
converts passwords to the shadow password format. The pwunconv command
|
||||
unconverts shadow passwords and generates a passwd file (a standard
|
||||
UNIX password file). The pwck command checks the integrity of password
|
||||
and shadow files. The lastlog command prints out the last login times
|
||||
for all users. The useradd, userdel, and usermod commands are used for
|
||||
managing user accounts. The groupadd, groupdel, and groupmod commands
|
||||
are used for managing group accounts.
|
||||
|
||||
## Sites
|
||||
* [Homepage](https://github.com/shadow-maint/shadow)
|
||||
* [Issue tracker](https://github.com/shadow-maint/shadow/issues)
|
||||
* [Releases](https://github.com/shadow-maint/shadow/releases)
|
||||
|
||||
## Contacts
|
||||
There are several ways to contact us:
|
||||
* [the general discussion mailing list](
|
||||
https://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-devel)
|
||||
* the #shadow IRC channel on libera.chat:
|
||||
* irc://irc.libera.chat/shadow
|
||||
|
||||
### Mailing archives
|
||||
* [the general discussion mailing list archive](
|
||||
https://alioth-lists.debian.net/pipermail/pkg-shadow-devel/)
|
||||
* [the commit mailing list archive](
|
||||
https://alioth-lists-archive.debian.net/pipermail/pkg-shadow-commits/),
|
||||
only used for historical purposes
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are welcome. Follow the
|
||||
[guidelines](doc/contributions/introduction.md) before posting any patches.
|
||||
|
||||
## Authors and maintainers
|
||||
Authors and maintainers are listed in [AUTHORS.md](
|
||||
https://github.com/shadow-maint/shadow/blob/master/AUTHORS.md).
|
||||
12
SECURITY.md
Normal file
12
SECURITY.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
At the moment only the latest release is supported.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Security vulnerabilities may be reported to
|
||||
* Serge Hallyn <serge@hallyn.com> (B175CFA98F192AF2)
|
||||
* Christian Brauner <christian@brauner.io> (4880B8C9BD0E5106FC070F4F7B3C391EFEA93624)
|
||||
* Iker Pedrosa <ipedrosa@redhat.com> (4E80EF49C7987B6DE2F81F5005079C6C3A653E57)
|
||||
6
TODO
6
TODO
@@ -1,4 +1,4 @@
|
||||
* Create a common usage function that'd take the array of
|
||||
* Create a common usage function that'd take the array of
|
||||
long options and an array of descriptions and output that so things would
|
||||
be standardized across the utils.
|
||||
Usage strings should be normalized and split first.
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
Check when RLOGIN is enabled if ruserok() exists
|
||||
|
||||
Move selinux_file_context out of libmisc/copydir.c
|
||||
Move selinux_file_context out of lib/copydir.c
|
||||
|
||||
Review hardcoded root account?
|
||||
|
||||
review all call to strto
|
||||
|
||||
libmisc/cleanup_user.c
|
||||
lib/cleanup_user.c
|
||||
cleanup needed (cleanup_report_add_user* not used)
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ AC_DEFUN([JH_PATH_XML_CATALOG],
|
||||
[
|
||||
# check for the presence of the XML catalog
|
||||
AC_ARG_WITH([xml-catalog],
|
||||
AC_HELP_STRING([--with-xml-catalog=CATALOG],
|
||||
AS_HELP_STRING([--with-xml-catalog=CATALOG],
|
||||
[path to xml catalog to use]),,
|
||||
[with_xml_catalog=/etc/xml/catalog])
|
||||
jh_found_xmlcatalog=true
|
||||
|
||||
@@ -4,6 +4,7 @@ autoreconf -v -f --install || exit 1
|
||||
|
||||
./configure \
|
||||
CFLAGS="-O2 -Wall" \
|
||||
--enable-lastlog \
|
||||
--enable-man \
|
||||
--enable-maintainer-mode \
|
||||
--enable-shared \
|
||||
|
||||
251
configure.ac
251
configure.ac
@@ -1,10 +1,10 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ([2.69])
|
||||
m4_define([libsubid_abi_major], 3)
|
||||
m4_define([libsubid_abi_major], 4)
|
||||
m4_define([libsubid_abi_minor], 0)
|
||||
m4_define([libsubid_abi_micro], 0)
|
||||
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
|
||||
AC_INIT([shadow], [4.9], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
AC_INIT([shadow], [4.14.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
[https://github.com/shadow-maint/shadow])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
@@ -20,59 +20,41 @@ dnl Some hacks...
|
||||
test "$prefix" = "NONE" && prefix="/usr"
|
||||
test "$prefix" = "/usr" && exec_prefix=""
|
||||
|
||||
AC_GNU_SOURCE
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
AM_ENABLE_STATIC
|
||||
AM_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
AC_ENABLE_SHARED
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_YACC
|
||||
AM_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_STDBOOL
|
||||
|
||||
AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
|
||||
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
|
||||
utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \
|
||||
gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \
|
||||
AC_CHECK_HEADERS(crypt.h utmp.h \
|
||||
termio.h sgtty.h sys/ioctl.h paths.h \
|
||||
sys/capability.h sys/random.h \
|
||||
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
|
||||
attr/libattr.h attr/error_context.h)
|
||||
|
||||
dnl shadow now uses the libc's shadow implementation
|
||||
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
|
||||
|
||||
AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \
|
||||
gethostname getentropy getrandom getspnam gettimeofday getusershell \
|
||||
getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \
|
||||
setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \
|
||||
getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \
|
||||
dlopen)
|
||||
AC_CHECK_FUNCS(arc4random_buf futimes \
|
||||
getentropy getrandom getspnam getusershell \
|
||||
initgroups lckpwdf lutimes mempcpy \
|
||||
setgroups updwtmp updwtmpx innetgr \
|
||||
getspnam_r \
|
||||
rpmatch \
|
||||
memset_explicit explicit_bzero stpecpy stpeprintf)
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_UID_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_MODE_T
|
||||
AC_HEADER_STAT
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
AC_CHECK_MEMBERS([struct stat.st_atim])
|
||||
AC_CHECK_MEMBERS([struct stat.st_atimensec])
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtim])
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtimensec])
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
AC_CHECK_MEMBERS([struct utmp.ut_type,
|
||||
struct utmp.ut_id,
|
||||
@@ -86,39 +68,11 @@ AC_CHECK_MEMBERS([struct utmp.ut_type,
|
||||
struct utmp.ut_xtime,
|
||||
struct utmp.ut_tv],,,[[#include <utmp.h>]])
|
||||
|
||||
AC_CHECK_MEMBERS([struct utmpx.ut_name,
|
||||
struct utmpx.ut_host,
|
||||
struct utmpx.ut_syslen,
|
||||
struct utmpx.ut_addr,
|
||||
struct utmpx.ut_addr_v6,
|
||||
struct utmpx.ut_time,
|
||||
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
|
||||
|
||||
if test "$ac_cv_header_lastlog_h" = "yes"; then
|
||||
AC_CACHE_CHECK(for ll_host in struct lastlog,
|
||||
ac_cv_struct_lastlog_ll_host,
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
|
||||
[struct lastlog ll; char *cp = ll.ll_host;]
|
||||
)],
|
||||
[ac_cv_struct_lastlog_ll_host=yes],
|
||||
[ac_cv_struct_lastlog_ll_host=no]
|
||||
)
|
||||
)
|
||||
|
||||
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
|
||||
AC_DEFINE(HAVE_LL_HOST, 1,
|
||||
[Define if struct lastlog has ll_host])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_TYPE_GETGROUPS
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_STRFTIME
|
||||
AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir)
|
||||
AC_REPLACE_FUNCS(putgrent putpwent putspent)
|
||||
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
|
||||
AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr)
|
||||
|
||||
AC_CHECK_FUNC(setpgrp)
|
||||
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
|
||||
@@ -130,6 +84,10 @@ if test "$ac_cv_header_shadow_h" = "yes"; then
|
||||
ac_cv_libc_shadowgrp,
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <shadow.h>
|
||||
#ifdef HAVE_GSHADOW_H
|
||||
#include <gshadow.h>
|
||||
#endif
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct sgrp *sg = sgetsgent("test:x::");
|
||||
@@ -205,14 +163,14 @@ AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
|
||||
[Path to passwd program.])
|
||||
|
||||
dnl XXX - quick hack, should disappear before anyone notices :).
|
||||
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog().])
|
||||
dnl XXX - I just read the above message :).
|
||||
if test "$ac_cv_func_ruserok" = "yes"; then
|
||||
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
|
||||
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(shadowgrp,
|
||||
[AC_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
|
||||
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_shadowgrp="yes" ;;
|
||||
no) enable_shadowgrp="no" ;;
|
||||
@@ -222,15 +180,15 @@ AC_ARG_ENABLE(shadowgrp,
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(man,
|
||||
[AC_HELP_STRING([--enable-man],
|
||||
[AS_HELP_STRING([--enable-man],
|
||||
[regenerate roff man pages from Docbook @<:@default=no@:>@])],
|
||||
[enable_man="${enableval}"],
|
||||
[enable_man="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(account-tools-setuid,
|
||||
[AC_HELP_STRING([--enable-account-tools-setuid],
|
||||
[Install the user and group management tools setuid and authenticate the callers. This requires --with-pam.])],
|
||||
[AS_HELP_STRING([--enable-account-tools-setuid],
|
||||
[Install the user and group management tools setuid and authenticate the callers. This requires --with-libpam.])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_acct_tools_setuid="yes" ;;
|
||||
no) enable_acct_tools_setuid="no" ;;
|
||||
@@ -240,77 +198,83 @@ AC_ARG_ENABLE(account-tools-setuid,
|
||||
[enable_acct_tools_setuid="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(utmpx,
|
||||
[AC_HELP_STRING([--enable-utmpx],
|
||||
[enable loggin in utmpx / wtmpx @<:@default=no@:>@])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_utmpx="yes" ;;
|
||||
no) enable_utmpx="no" ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-utmpx) ;;
|
||||
esac],
|
||||
[enable_utmpx="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(subordinate-ids,
|
||||
[AC_HELP_STRING([--enable-subordinate-ids],
|
||||
[AS_HELP_STRING([--enable-subordinate-ids],
|
||||
[support subordinate ids @<:@default=yes@:>@])],
|
||||
[enable_subids="${enableval}"],
|
||||
[enable_subids="maybe"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(lastlog,
|
||||
[AS_HELP_STRING([--enable-lastlog],
|
||||
[enable lastlog @<:@default=no@:>@])],
|
||||
[enable_lastlog="${enableval}"],
|
||||
[enable_lastlog="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(logind,
|
||||
[AS_HELP_STRING([--enable-logind],
|
||||
[enable logind @<:@default=yes@:>@])],
|
||||
[enable_logind="${enableval}"],
|
||||
[enable_logind="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(audit,
|
||||
[AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
|
||||
[with_audit=$withval], [with_audit=maybe])
|
||||
AC_ARG_WITH(libpam,
|
||||
[AC_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
|
||||
[with_libpam=$withval], [with_libpam=maybe])
|
||||
AC_ARG_WITH(btrfs,
|
||||
[AC_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
|
||||
[with_btrfs=$withval], [with_btrfs=maybe])
|
||||
AC_ARG_WITH(selinux,
|
||||
[AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
|
||||
[with_selinux=$withval], [with_selinux=maybe])
|
||||
AC_ARG_WITH(acl,
|
||||
[AC_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
|
||||
[with_acl=$withval], [with_acl=maybe])
|
||||
AC_ARG_WITH(attr,
|
||||
[AC_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
|
||||
[with_attr=$withval], [with_attr=maybe])
|
||||
AC_ARG_WITH(skey,
|
||||
[AC_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
|
||||
[AS_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
|
||||
[with_skey=$withval], [with_skey=no])
|
||||
AC_ARG_WITH(tcb,
|
||||
[AC_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
|
||||
[AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
|
||||
[with_tcb=$withval], [with_tcb=maybe])
|
||||
AC_ARG_WITH(libcrack,
|
||||
[AC_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])],
|
||||
[AS_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])],
|
||||
[with_libcrack=$withval], [with_libcrack=no])
|
||||
AC_ARG_WITH(sha-crypt,
|
||||
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
|
||||
[AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
|
||||
[with_sha_crypt=$withval], [with_sha_crypt=yes])
|
||||
AC_ARG_WITH(bcrypt,
|
||||
[AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[AS_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[with_bcrypt=$withval], [with_bcrypt=no])
|
||||
AC_ARG_WITH(yescrypt,
|
||||
[AC_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[AS_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[with_yescrypt=$withval], [with_yescrypt=no])
|
||||
AC_ARG_WITH(nscd,
|
||||
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
|
||||
[AS_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
|
||||
[with_nscd=$withval], [with_nscd=yes])
|
||||
AC_ARG_WITH(sssd,
|
||||
[AC_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])],
|
||||
[AS_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])],
|
||||
[with_sssd=$withval], [with_sssd=yes])
|
||||
AC_ARG_WITH(group-name-max-length,
|
||||
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
|
||||
[AS_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=32@:>@])],
|
||||
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
|
||||
AC_ARG_WITH(su,
|
||||
[AC_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
|
||||
[AS_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
|
||||
[with_su=$withval], [with_su=yes])
|
||||
AC_ARG_WITH(libbsd,
|
||||
[AS_HELP_STRING([--with-libbsd], [use libbsd support @<:@default=yes if found@:>@])],
|
||||
[with_libbsd=$withval], [with_libbsd=yes])
|
||||
|
||||
if test "$with_group_name_max_length" = "no" ; then
|
||||
with_group_name_max_length=0
|
||||
elif test "$with_group_name_max_length" = "yes" ; then
|
||||
with_group_name_max_length=16
|
||||
with_group_name_max_length=32
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max group name length])
|
||||
AC_SUBST(GROUP_NAME_MAX_LENGTH)
|
||||
@@ -343,19 +307,19 @@ if test "$with_sssd" = "yes"; then
|
||||
[AC_MSG_ERROR([posix_spawn is needed for sssd support])])
|
||||
fi
|
||||
|
||||
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su])])
|
||||
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su]))
|
||||
AM_CONDITIONAL([WITH_SU], [test "x$with_su" != "xno"])
|
||||
|
||||
dnl Check for some functions in libc first, only if not found check for
|
||||
dnl other libraries. This should prevent linking libnsl if not really
|
||||
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
||||
|
||||
AC_SEARCH_LIBS(inet_ntoa, inet)
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||
|
||||
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
|
||||
if test -n "$LIBECONF"; then
|
||||
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
|
||||
[Directory for distribution provided configuration files])
|
||||
ECONF_CPPFLAGS="-DUSE_ECONF=1"
|
||||
AC_ARG_ENABLE([vendordir],
|
||||
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
|
||||
@@ -363,6 +327,9 @@ fi
|
||||
AC_SUBST(ECONF_CPPFLAGS)
|
||||
AC_SUBST(LIBECONF)
|
||||
AC_SUBST([VENDORDIR], [$enable_vendordir])
|
||||
if test "x$enable_vendordir" != x; then
|
||||
AC_DEFINE(HAVE_VENDORDIR, 1, [Define to support vendor settings.])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
|
||||
|
||||
if test "$enable_shadowgrp" = "yes"; then
|
||||
@@ -407,6 +374,39 @@ if test "$enable_subids" != "no"; then
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno")
|
||||
|
||||
if test "$enable_lastlog" = "yes" && test "$ac_cv_header_lastlog_h" = "yes"; then
|
||||
AC_CACHE_CHECK(for ll_host in struct lastlog,
|
||||
ac_cv_struct_lastlog_ll_host,
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
|
||||
[struct lastlog ll; char *cp = ll.ll_host;]
|
||||
)],
|
||||
[ac_cv_struct_lastlog_ll_host=yes],
|
||||
[ac_cv_struct_lastlog_ll_host=no]
|
||||
)
|
||||
)
|
||||
|
||||
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
|
||||
AC_DEFINE(HAVE_LL_HOST, 1,
|
||||
[Define if struct lastlog has ll_host])
|
||||
AC_DEFINE(ENABLE_LASTLOG, 1, [Define to support lastlog.])
|
||||
enable_lastlog="yes"
|
||||
else
|
||||
AC_MSG_ERROR([Cannot enable support for lastlog on systems where the data structures aren't available])
|
||||
enable_subids="no"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LASTLOG, test "x$enable_lastlog" != "xno")
|
||||
|
||||
AC_SUBST(LIBSYSTEMD)
|
||||
if test "$enable_logind" = "yes"; then
|
||||
AC_CHECK_LIB(systemd, sd_session_get_remote_host,
|
||||
[enable_logind="yes"; [LIBSYSTEMD=-lsystemd];
|
||||
AC_DEFINE(ENABLE_LOGIND, 1,
|
||||
[Define to manage session support with logind.])],
|
||||
[enable_logind="no"])
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LOGIND, test "x$enable_logind" != "xno")
|
||||
|
||||
AC_SUBST(LIBCRYPT)
|
||||
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
|
||||
[AC_MSG_ERROR([crypt() not found])])
|
||||
@@ -415,6 +415,29 @@ AC_SUBST(LIYESCRYPT)
|
||||
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
|
||||
[AC_MSG_ERROR([crypt() not found])])
|
||||
|
||||
AC_SUBST(LIBBSD)
|
||||
if test "$with_libbsd" != "no"; then
|
||||
AC_SEARCH_LIBS([readpassphrase], [bsd], [], [
|
||||
AC_MSG_ERROR([readpassphrase() is missing, either from libc or libbsd])
|
||||
])
|
||||
AS_IF([test "$ac_cv_search_readpassphrase" = "-lbsd"], [
|
||||
PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay])
|
||||
])
|
||||
dnl Make sure either the libc or libbsd provide the header.
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
|
||||
AC_CHECK_HEADERS([readpassphrase.h])
|
||||
AS_IF([test "$ac_cv_header_readpassphrase_h" != "yes"], [
|
||||
AC_MSG_ERROR([readpassphrase.h is missing])
|
||||
])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
AC_DEFINE(WITH_LIBBSD, 1, [Build shadow with libbsd support])
|
||||
else
|
||||
AC_DEFINE(WITH_LIBBSD, 0, [Build shadow without libbsd support])
|
||||
AC_CHECK_FUNC(strlcpy, [], [AC_MSG_ERROR([strlcpy is required from glibc >= 2.38 or libbsd])])
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_LIBBSD, test x$with_libbsd = xyes)
|
||||
|
||||
AC_SUBST(LIBACL)
|
||||
if test "$with_acl" != "no"; then
|
||||
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
|
||||
@@ -670,7 +693,7 @@ AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
|
||||
|
||||
|
||||
AC_ARG_WITH(fcaps,
|
||||
[AC_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
|
||||
[AS_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
|
||||
[with_fcaps=$withval], [with_fcaps=no])
|
||||
AM_CONDITIONAL(FCAPS, test "x$with_fcaps" = "xyes")
|
||||
|
||||
@@ -688,26 +711,19 @@ if test "$with_skey" = "yes"; then
|
||||
AC_CHECK_LIB(skey, skeychallenge, [LIBSKEY=-lskey],
|
||||
[AC_MSG_ERROR([liskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
|
||||
AC_DEFINE(SKEY, 1, [Define to support S/Key logins.])
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdio.h>
|
||||
#include <skey.h>
|
||||
],[
|
||||
]], [[
|
||||
skeychallenge((void*)0, (void*)0, (void*)0, 0);
|
||||
],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])])
|
||||
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
|
||||
fi
|
||||
|
||||
if test "$enable_utmpx" = "yes"; then
|
||||
if test "$ac_cv_header_utmpx_h" != "yes"; then
|
||||
AC_MSG_ERROR([The utmpx.h header file is required for utmpx support.])
|
||||
fi
|
||||
AC_DEFINE(USE_UTMPX,
|
||||
1,
|
||||
[Define if utmpx should be used])
|
||||
fi
|
||||
AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
|
||||
|
||||
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
|
||||
|
||||
AM_GNU_GETTEXT_VERSION(0.16)
|
||||
AM_GNU_GETTEXT_VERSION([0.19])
|
||||
AM_GNU_GETTEXT([external], [need-ngettext])
|
||||
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
|
||||
|
||||
@@ -734,15 +750,17 @@ AC_CONFIG_FILES([
|
||||
man/ru/Makefile
|
||||
man/sv/Makefile
|
||||
man/tr/Makefile
|
||||
man/uk/Makefile
|
||||
man/zh_CN/Makefile
|
||||
man/zh_TW/Makefile
|
||||
libmisc/Makefile
|
||||
lib/Makefile
|
||||
libsubid/Makefile
|
||||
libsubid/subid.h
|
||||
src/Makefile
|
||||
contrib/Makefile
|
||||
etc/Makefile
|
||||
etc/pam.d/Makefile
|
||||
etc/shadow-maint/Makefile
|
||||
shadow.spec
|
||||
])
|
||||
AC_OUTPUT
|
||||
@@ -769,6 +787,9 @@ echo " yescrypt passwords encryption: $with_yescrypt"
|
||||
echo " nscd support: $with_nscd"
|
||||
echo " sssd support: $with_sssd"
|
||||
echo " subordinate IDs support: $enable_subids"
|
||||
echo " enable lastlog: $enable_lastlog"
|
||||
echo " enable logind: $enable_logind"
|
||||
echo " use file caps: $with_fcaps"
|
||||
echo " install su: $with_su"
|
||||
echo " enabled vendor dir: $enable_vendordir"
|
||||
echo
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This is a dummy Makefile.am to get automake work flawlessly,
|
||||
# and also cooperate to make a distribution for `make dist'
|
||||
|
||||
EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \
|
||||
atudel groupmems.shar pwdauth.c shadow-anonftp.patch \
|
||||
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh \
|
||||
atudel groupmems.shar shadow-anonftp.patch \
|
||||
udbachk.tgz
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
/****
|
||||
** 03/17/96
|
||||
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
|
||||
** --marekm
|
||||
**
|
||||
** 02/26/96
|
||||
** modified to call shadow utils (useradd,chage,passwd) on shadowed
|
||||
** systems - Cristian Gafton, gafton@sorosis.ro
|
||||
**
|
||||
** 6/27/95
|
||||
** shadow-adduser 1.4:
|
||||
**
|
||||
** now it copies the /etc/skel dir into the person's dir,
|
||||
** makes the mail folders, changed some defaults and made a 'make
|
||||
** install' just for the hell of it.
|
||||
**
|
||||
** Greg Gallagher
|
||||
** CIN.Net
|
||||
**
|
||||
** 1/28/95
|
||||
** shadow-adduser 1.3:
|
||||
**
|
||||
** Basically a bug-fix on my additions in 1.2. Thanks to Terry Stewart
|
||||
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
|
||||
** It was such a stupid bug that I would have never seen it myself.
|
||||
**
|
||||
** Brandon
|
||||
*****
|
||||
** 01/27/95
|
||||
**
|
||||
** shadow-adduser 1.2:
|
||||
** I took the C source from adduser-shadow (credits are below) and made
|
||||
** it a little more worthwhile. Many small changes... Here's
|
||||
** the ones I can remember:
|
||||
**
|
||||
** Removed support for non-shadowed systems (if you don't have shadow,
|
||||
** use the original adduser, don't get this shadow version!)
|
||||
** Added support for the correct /etc/shadow fields (Min days before
|
||||
** password change, max days before password change, Warning days,
|
||||
** and how many days from expiry date does the account go invalid)
|
||||
** The previous version just left all of those fields blank.
|
||||
** There is still one field left (expiry date for the account, period)
|
||||
** which I have left blank because I do not use it and didn't want to
|
||||
** spend any more time on this. I'm sure someone will put it in and
|
||||
** tack another plethora of credits on here. :)
|
||||
** Added in the password date field, which should always reflect the last
|
||||
** date the password was changed, for expiry purposes. "passwd" always
|
||||
** updates this field, so the adduser program should set it up right
|
||||
** initially (or a user could keep thier initial password forever ;)
|
||||
** The number is in days since Jan 1st, 1970.
|
||||
**
|
||||
** Have fun with it, and someone please make
|
||||
** a real version(this is still just a hack)
|
||||
** for us all to use (and Email it to me???)
|
||||
**
|
||||
** Brandon
|
||||
** photon@usis.com
|
||||
**
|
||||
*****
|
||||
** adduser 1.0: add a new user account (For systems not using shadow)
|
||||
** With a nice little interface and a will to do all the work for you.
|
||||
**
|
||||
** Craig Hagan
|
||||
** hagan@opine.cs.umass.edu
|
||||
**
|
||||
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
|
||||
** chris@slinky.cs.umass.edu
|
||||
**
|
||||
*****
|
||||
**
|
||||
** 01/19/95
|
||||
**
|
||||
** FURTHER modifications to enable shadow passwd support (kludged, but
|
||||
** no more so than the original) by Dan Crowson - dcrowson@mo.net
|
||||
**
|
||||
** Search on DAN for all changes...
|
||||
**
|
||||
*****
|
||||
**
|
||||
** cc -O -o adduser adduser.c
|
||||
** Use gcc if you have it... (political reasons beyond my control) (chris)
|
||||
**
|
||||
** I've gotten this program to work with success under Linux (without
|
||||
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
|
||||
** on any system that uses no shadow. (chris)
|
||||
**
|
||||
** If you have no crypt() then try
|
||||
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
|
||||
** I'm not sure how login operates with no crypt()... I guess
|
||||
** the same way we're doing it here.
|
||||
*/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
|
||||
#define DEFAULT_HOME "/home"
|
||||
#define USERADD_PATH "/usr/sbin/useradd"
|
||||
#define CHAGE_PATH "/usr/sbin/chage"
|
||||
#define PASSWD_PATH "/usr/bin/passwd"
|
||||
#define DEFAULT_GROUP 100
|
||||
|
||||
#define DEFAULT_MAX_PASS 60
|
||||
#define DEFAULT_WARN_PASS 10
|
||||
/* if you use this feature, you will get a lot of complaints from users
|
||||
who rarely use their accounts :) (something like 3 months would be
|
||||
more reasonable) --marekm */
|
||||
#define DEFAULT_USER_DIE /* 10 */ 0
|
||||
|
||||
void main()
|
||||
{
|
||||
char foo[32];
|
||||
char uname[9],person[32],dir[32],shell[32];
|
||||
unsigned int group,min_pass,max_pass,warn_pass,user_die;
|
||||
/* the group and uid of the new user */
|
||||
int bad=0,done=0,correct=0,gets_warning=0;
|
||||
char cmd[255];
|
||||
struct group *grp;
|
||||
|
||||
/* flags, in order:
|
||||
* bad to see if the username is in /etc/passwd, or if strange stuff has
|
||||
* been typed if the user might be put in group 0
|
||||
* done allows the program to exit when a user has been added
|
||||
* correct loops until a password is found that isn't in /etc/passwd
|
||||
* gets_warning allows the fflush to be skipped for the first gets
|
||||
* so that output is still legible
|
||||
*/
|
||||
|
||||
/* The real program starts HERE! */
|
||||
|
||||
if(geteuid()!=0)
|
||||
{
|
||||
printf("It seems you don't have access to add a new user. Try\n");
|
||||
printf("logging in as root or su root to gain super-user access.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Sanity checks
|
||||
*/
|
||||
|
||||
if (!(grp=getgrgid(DEFAULT_GROUP))){
|
||||
printf("Error: the default group %d does not exist on this system!\n",
|
||||
DEFAULT_GROUP);
|
||||
printf("adduser must be recompiled.\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
while(!correct) { /* loop until a "good" uname is chosen */
|
||||
while(!done) {
|
||||
printf("\nLogin to add (^C to quit): ");
|
||||
if(gets_warning) /* if the warning was already shown */
|
||||
fflush(stdout); /* fflush stdout, otherwise set the flag */
|
||||
else
|
||||
gets_warning=1;
|
||||
|
||||
gets(uname);
|
||||
if(!strlen(uname)) {
|
||||
printf("Empty input.\n");
|
||||
done=0;
|
||||
continue;
|
||||
};
|
||||
|
||||
/* what I saw here before made me think maybe I was running DOS */
|
||||
/* might this be a solution? (chris) */
|
||||
if (getpwnam(uname) != NULL) {
|
||||
printf("That name is in use, choose another.\n");
|
||||
done=0;
|
||||
} else
|
||||
done=1;
|
||||
}; /* done, we have a valid new user name */
|
||||
|
||||
/* all set, get the rest of the stuff */
|
||||
printf("\nEditing information for new user [%s]\n",uname);
|
||||
|
||||
printf("\nFull Name [%s]: ",uname);
|
||||
gets(person);
|
||||
if (!strlen(person)) {
|
||||
bzero(person,sizeof(person));
|
||||
strcpy(person,uname);
|
||||
};
|
||||
|
||||
do {
|
||||
bad=0;
|
||||
printf("GID [%d]: ",DEFAULT_GROUP);
|
||||
gets(foo);
|
||||
if (!strlen(foo))
|
||||
group=DEFAULT_GROUP;
|
||||
else
|
||||
if (isdigit (*foo)) {
|
||||
group = atoi(foo);
|
||||
if (! (grp = getgrgid (group))) {
|
||||
printf("unknown gid %s\n",foo);
|
||||
group=DEFAULT_GROUP;
|
||||
bad=1;
|
||||
};
|
||||
} else
|
||||
if ((grp = getgrnam (foo)))
|
||||
group = grp->gr_gid;
|
||||
else {
|
||||
printf("unknown group %s\n",foo);
|
||||
group=DEFAULT_GROUP;
|
||||
bad=1;
|
||||
}
|
||||
if (group==0){ /* You're not allowed to make root group users! */
|
||||
printf("Creation of root group users not allowed (must be done by hand)\n");
|
||||
group=DEFAULT_GROUP;
|
||||
bad=1;
|
||||
};
|
||||
} while(bad);
|
||||
|
||||
|
||||
fflush(stdin);
|
||||
|
||||
printf("\nIf home dir ends with a / then [%s] will be appended to it\n",uname);
|
||||
printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname);
|
||||
fflush(stdout);
|
||||
gets(dir);
|
||||
if (!strlen(dir)) { /* hit return */
|
||||
sprintf(dir,"%s/%s",DEFAULT_HOME,uname);
|
||||
fflush(stdin);
|
||||
} else
|
||||
if (dir[strlen(dir)-1]=='/')
|
||||
sprintf(dir+strlen(dir),"%s",uname);
|
||||
|
||||
printf("\nShell [%s]: ",DEFAULT_SHELL);
|
||||
fflush(stdout);
|
||||
gets(shell);
|
||||
if (!strlen(shell))
|
||||
sprintf(shell,"%s",DEFAULT_SHELL);
|
||||
|
||||
printf("\nMin. Password Change Days [0]: ");
|
||||
gets(foo);
|
||||
min_pass=atoi(foo);
|
||||
|
||||
printf("Max. Password Change Days [%d]: ",DEFAULT_MAX_PASS);
|
||||
gets(foo);
|
||||
if (strlen(foo) > 1)
|
||||
max_pass = atoi(foo);
|
||||
else
|
||||
max_pass = DEFAULT_MAX_PASS;
|
||||
|
||||
printf("Password Warning Days [%d]: ",DEFAULT_WARN_PASS);
|
||||
gets(foo);
|
||||
warn_pass = atoi(foo);
|
||||
if (warn_pass==0)
|
||||
warn_pass = DEFAULT_WARN_PASS;
|
||||
|
||||
printf("Days after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE);
|
||||
gets(foo);
|
||||
user_die = atoi(foo);
|
||||
if (user_die == 0)
|
||||
user_die = DEFAULT_USER_DIE;
|
||||
|
||||
printf("\nInformation for new user [%s] [%s]:\n",uname,person);
|
||||
printf("Home directory: [%s] Shell: [%s]\n",dir,shell);
|
||||
printf("GID: [%d]\n",group);
|
||||
printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
|
||||
min_pass,max_pass,warn_pass,user_die);
|
||||
printf("\nIs this correct? [y/N]: ");
|
||||
fflush(stdout);
|
||||
gets(foo);
|
||||
|
||||
done=bad=correct=(foo[0]=='y'||foo[0]=='Y');
|
||||
|
||||
if(bad!=1)
|
||||
printf("\nUser [%s] not added\n",uname);
|
||||
}
|
||||
|
||||
bzero(cmd,sizeof(cmd));
|
||||
sprintf(cmd,"%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
|
||||
USERADD_PATH,group,dir,shell,person,uname);
|
||||
printf("Calling useradd to add new user:\n%s\n",cmd);
|
||||
if(system(cmd)){
|
||||
printf("User add failed!\n");
|
||||
exit(errno);
|
||||
};
|
||||
bzero(cmd,sizeof(cmd));
|
||||
sprintf(cmd,"%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
|
||||
min_pass,max_pass,warn_pass,user_die,uname);
|
||||
printf("%s\n",cmd);
|
||||
if(system(cmd)){
|
||||
printf("There was an error setting password expire values\n");
|
||||
exit(errno);
|
||||
};
|
||||
bzero(cmd,sizeof(cmd));
|
||||
sprintf(cmd,"%s %s",PASSWD_PATH,uname);
|
||||
system(cmd);
|
||||
printf("\nDone.\n");
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
** Added in the password date field, which should always reflect the last
|
||||
** date the password was changed, for expiry purposes. "passwd" always
|
||||
** updates this field, so the adduser program should set it up right
|
||||
** initially (or a user could keep thier initial password forever ;)
|
||||
** initially (or a user could keep their initial password forever ;)
|
||||
** The number is in days since Jan 1st, 1970.
|
||||
**
|
||||
** Have fun with it, and someone please make
|
||||
@@ -489,7 +489,7 @@ safeget (char *buf, int maxlen)
|
||||
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
|
||||
{
|
||||
bad = (!isalnum (c) && (c != '_') && (c != ' '));
|
||||
*(buf++) = (char) c;
|
||||
*(buf++) = c;
|
||||
}
|
||||
*buf = '\0';
|
||||
|
||||
|
||||
@@ -1,34 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright (c) 1996 Brian R. Gaeke
|
||||
# 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. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by Brian R. Gaeke.
|
||||
# 4. The name of the author, Brian R. Gaeke, may not be used to endorse
|
||||
# or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY BRIAN R. GAEKE ``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 BRIAN R. GAEKE 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.
|
||||
# SPDX-FileCopyrightText: 1996 Brian R. Gaeke
|
||||
# SPDX-License-Identifier: BSD-4-Clause
|
||||
#
|
||||
# Additionally:
|
||||
#
|
||||
|
||||
@@ -76,36 +76,9 @@ else
|
||||
$echo 'x -' extracting 'Makefile' '(text)'
|
||||
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
|
||||
/*
|
||||
# Copyright 2000, International Business Machines, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# original author: George Kraft IV, gk4@us.ibm.com
|
||||
#
|
||||
# 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 International Business Machines, 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 INTERNATIONAL BUSINESS MACHINES, 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
|
||||
# INTERNATIONAL BUSINESS MACHINES, 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.
|
||||
# SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
||||
# SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
X
|
||||
all: groupmems
|
||||
@@ -143,36 +116,9 @@ else
|
||||
$echo 'x -' extracting 'groupmems.c' '(text)'
|
||||
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
|
||||
/*
|
||||
X * Copyright 2000, International Business Machines, Inc.
|
||||
X * All rights reserved.
|
||||
X *
|
||||
X * original author: George Kraft IV, gk4@us.ibm.com
|
||||
X *
|
||||
X * Redistribution and use in source and binary forms, with or without
|
||||
X * modification, are permitted provided that the following conditions
|
||||
X * are met:
|
||||
X *
|
||||
X * 1. Redistributions of source code must retain the above copyright
|
||||
X * notice, this list of conditions and the following disclaimer.
|
||||
X * 2. Redistributions in binary form must reproduce the above copyright
|
||||
X * notice, this list of conditions and the following disclaimer in the
|
||||
X * documentation and/or other materials provided with the distribution.
|
||||
X * 3. Neither the name of International Business Machines, Inc., nor the
|
||||
X * names of its contributors may be used to endorse or promote products
|
||||
X * derived from this software without specific prior written permission.
|
||||
X *
|
||||
X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
|
||||
X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
|
||||
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
X * SUCH DAMAGE.
|
||||
X * SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
||||
X * SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
||||
X * SPDX-License-Identifier: BSD-3-Clause
|
||||
X */
|
||||
/*
|
||||
**
|
||||
@@ -436,36 +382,9 @@ else
|
||||
$echo 'x -' extracting 'groupmems.8' '(text)'
|
||||
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
|
||||
X.\"
|
||||
X.\" Copyright 2000, International Business Machines, Inc.
|
||||
X.\" All rights reserved.
|
||||
X.\"
|
||||
X.\" original author: George Kraft IV, gk4@us.ibm.com
|
||||
X.\"
|
||||
X.\" Redistribution and use in source and binary forms, with or without
|
||||
X.\" modification, are permitted provided that the following conditions
|
||||
X.\" are met:
|
||||
X.\"
|
||||
X.\" 1. Redistributions of source code must retain the above copyright
|
||||
X.\" notice, this list of conditions and the following disclaimer.
|
||||
X.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
X.\" notice, this list of conditions and the following disclaimer in the
|
||||
X.\" documentation and/or other materials provided with the distribution.
|
||||
X.\" 3. Neither the name of International Business Machines, Inc., nor the
|
||||
X.\" names of its contributors may be used to endorse or promote products
|
||||
X.\" derived from this software without specific prior written permission.
|
||||
X.\"
|
||||
X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
|
||||
X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
|
||||
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
X.\" SUCH DAMAGE.
|
||||
X.\" SPDX-FileCopyrightText: 2000, International Business Machines, Inc.
|
||||
X.\" SPDX-FileCopyrightText: 2000, George Kraft IV, gk4@us.ibm.com
|
||||
X.\" SPDX-License-Identifier: BSD-3-Clause
|
||||
X.\"
|
||||
X.\" $Id$
|
||||
X.\"
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* pwdauth.c - program to verify a given username/password pair.
|
||||
*
|
||||
* Run it with username in argv[1] (may be omitted - default is the
|
||||
* current user), and send it the password over a pipe on stdin.
|
||||
* Exit status: 0 - correct password, 1 - wrong password, >1 - other
|
||||
* errors. For use with shadow passwords, this program should be
|
||||
* installed setuid root.
|
||||
*
|
||||
* This can be used, for example, by xlock - you don't have to install
|
||||
* this large and complex (== possibly insecure) program setuid root,
|
||||
* just modify it to run this simple program to do the authentication.
|
||||
*
|
||||
* Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
|
||||
* soon as possible after getting the user's encrypted password.
|
||||
* Using this program probably doesn't make it more secure, and has one
|
||||
* disadvantage: since we don't get the encrypted user's password at
|
||||
* startup (but at the time the user is authenticated), it is not clear
|
||||
* how we should handle errors (like getpwnam() returning NULL).
|
||||
* - fail the authentication? Problem: no way to unlock (other than kill
|
||||
* the process from somewhere else) if the NIS server stops responding.
|
||||
* - succeed and unlock? Problem: it's too easy to unlock by unplugging
|
||||
* the box from the network and waiting until NIS times out...
|
||||
*
|
||||
* This program is Copyright (C) 1996 Marek Michalkiewicz
|
||||
* <marekm@i17linuxb.ists.pwr.wroc.pl>.
|
||||
*
|
||||
* It may be used and distributed freely for any purposes. There is no
|
||||
* warranty - use at your own risk. I am not liable for any damages etc.
|
||||
* If you improve it, please send me your changes.
|
||||
*/
|
||||
|
||||
static char rcsid[] = "$Id$";
|
||||
|
||||
/*
|
||||
* Define USE_SYSLOG to use syslog() to log successful and failed
|
||||
* authentication. This should be safe even if your system has
|
||||
* the infamous syslog buffer overrun security problem...
|
||||
*/
|
||||
#define USE_SYSLOG
|
||||
|
||||
/*
|
||||
* Define HAVE_GETSPNAM to get shadow passwords using getspnam().
|
||||
* Some systems don't have getspnam(), but getpwnam() returns
|
||||
* encrypted passwords only if running as root.
|
||||
*
|
||||
* According to the xlock source (not tested, except Linux) -
|
||||
* define: Linux, Solaris 2.x, SVR4, ...
|
||||
* undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
|
||||
* Known not supported (yet): Ultrix, OSF/1, SCO.
|
||||
*/
|
||||
#define HAVE_GETSPNAM
|
||||
|
||||
/*
|
||||
* Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
|
||||
* pw_encrypt() is like the standard crypt(), except that it may
|
||||
* support better password hashing algorithms.
|
||||
*
|
||||
* Define if linking with libshadow.a from the shadow password
|
||||
* suite (Linux, SunOS 4.x?).
|
||||
*/
|
||||
#undef HAVE_PW_ENCRYPT
|
||||
|
||||
/*
|
||||
* Define HAVE_AUTH_METHODS to support the shadow suite specific
|
||||
* extension: the encrypted password field contains a list of
|
||||
* administrator defined authentication methods, separated by
|
||||
* semicolons. This program only supports the standard password
|
||||
* authentication method (a string that doesn't start with '@').
|
||||
*/
|
||||
#undef HAVE_AUTH_METHODS
|
||||
|
||||
/*
|
||||
* FAIL_DELAY - number of seconds to sleep before exiting if the
|
||||
* password was wrong, to slow down password guessing attempts.
|
||||
*/
|
||||
#define FAIL_DELAY 2
|
||||
|
||||
/* No user-serviceable parts below :-). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
#include <syslog.h>
|
||||
#ifndef LOG_AUTHPRIV
|
||||
#define LOG_AUTHPRIV LOG_AUTH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETSPNAM
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PW_ENCRYPT
|
||||
extern char *pw_encrypt();
|
||||
#define crypt pw_encrypt
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read the password (one line) from fp. We don't turn off echo
|
||||
* because we expect input from a pipe.
|
||||
*/
|
||||
static char *
|
||||
get_line(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
static char buf[128];
|
||||
char *cp;
|
||||
int ch;
|
||||
|
||||
cp = buf;
|
||||
while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
|
||||
if (cp >= buf + sizeof buf - 1)
|
||||
break;
|
||||
*cp++ = ch;
|
||||
}
|
||||
*cp = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the password file entry for the current user. If the name
|
||||
* returned by getlogin() is correct (matches the current real uid),
|
||||
* return the entry for that user. Otherwise, return the entry (if
|
||||
* any) matching the current real uid. Return NULL on failure.
|
||||
*/
|
||||
static struct passwd *
|
||||
get_my_pwent()
|
||||
{
|
||||
uid_t uid = getuid();
|
||||
char *name = getlogin();
|
||||
|
||||
if (name && *name) {
|
||||
struct passwd *pw = getpwnam(name);
|
||||
|
||||
if (pw && pw->pw_uid == uid)
|
||||
return pw;
|
||||
}
|
||||
return getpwuid(uid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the password. The system-dependent shadow support is here.
|
||||
*/
|
||||
static int
|
||||
password_auth_ok(pw, pass)
|
||||
const struct passwd *pw;
|
||||
const char *pass;
|
||||
{
|
||||
int result;
|
||||
char *cp;
|
||||
#ifdef HAVE_AUTH_METHODS
|
||||
char *buf;
|
||||
#endif
|
||||
#ifdef HAVE_GETSPNAM
|
||||
struct spwd *sp;
|
||||
#endif
|
||||
|
||||
if (pw) {
|
||||
#ifdef HAVE_GETSPNAM
|
||||
sp = getspnam(pw->pw_name);
|
||||
if (sp)
|
||||
cp = sp->sp_pwdp;
|
||||
else
|
||||
#endif
|
||||
cp = pw->pw_passwd;
|
||||
} else
|
||||
cp = "xx";
|
||||
|
||||
#ifdef HAVE_AUTH_METHODS
|
||||
buf = strdup(cp); /* will be modified by strtok() */
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
exit(13);
|
||||
}
|
||||
cp = strtok(buf, ";");
|
||||
while (cp && *cp == '@')
|
||||
cp = strtok(NULL, ";");
|
||||
|
||||
/* fail if no password authentication for this user */
|
||||
if (!cp)
|
||||
cp = "xx";
|
||||
#endif
|
||||
|
||||
if (*pass || *cp)
|
||||
result = (strcmp(crypt(pass, cp), cp) == 0);
|
||||
else
|
||||
result = 1; /* user with no password */
|
||||
|
||||
#ifdef HAVE_AUTH_METHODS
|
||||
free(buf);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main program.
|
||||
*/
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct passwd *pw;
|
||||
char *pass, *name;
|
||||
char myname[32];
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
|
||||
#endif
|
||||
pw = get_my_pwent();
|
||||
if (!pw) {
|
||||
#ifdef USE_SYSLOG
|
||||
syslog(LOG_ERR, "can't get login name for uid %d.\n",
|
||||
(int) getuid());
|
||||
#endif
|
||||
fprintf(stderr, "Who are you?\n");
|
||||
exit(2);
|
||||
}
|
||||
strncpy(myname, pw->pw_name, sizeof myname - 1);
|
||||
myname[sizeof myname - 1] = '\0';
|
||||
name = myname;
|
||||
|
||||
if (argc > 1) {
|
||||
name = argv[1];
|
||||
pw = getpwnam(name);
|
||||
}
|
||||
|
||||
pass = get_line(stdin);
|
||||
if (password_auth_ok(pw, pass)) {
|
||||
#ifdef USE_SYSLOG
|
||||
syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
|
||||
"user `%s' entered correct password for `%.32s'.\n",
|
||||
myname, name);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
#ifdef USE_SYSLOG
|
||||
/* be careful not to overrun the syslog buffer */
|
||||
syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
|
||||
"user `%s' entered incorrect password for `%.32s'.\n",
|
||||
myname, name);
|
||||
#endif
|
||||
#ifdef FAIL_DELAY
|
||||
sleep(FAIL_DELAY);
|
||||
#endif
|
||||
fprintf(stderr, "Wrong password.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* You can use code similar to the following to run this program.
|
||||
* Return values: >=0 - program exit status (use the <sys/wait.h>
|
||||
* macros to get the exit code, it is shifted left by 8 bits),
|
||||
* -1 - check errno.
|
||||
*/
|
||||
int
|
||||
verify_password(const char *username, const char *password)
|
||||
{
|
||||
int pipe_fd[2];
|
||||
int pid, wpid, status;
|
||||
|
||||
if (pipe(pipe_fd))
|
||||
return -1;
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
char *arg[3];
|
||||
char *env[1];
|
||||
|
||||
/* child */
|
||||
close(pipe_fd[1]);
|
||||
if (pipe_fd[0] != 0) {
|
||||
if (dup2(pipe_fd[0], 0) != 0)
|
||||
_exit(127);
|
||||
close(pipe_fd[0]);
|
||||
}
|
||||
arg[0] = "/usr/bin/pwdauth";
|
||||
arg[1] = username;
|
||||
arg[2] = NULL;
|
||||
env[0] = NULL;
|
||||
execve(arg[0], arg, env);
|
||||
_exit(127);
|
||||
} else if (pid == -1) {
|
||||
/* error */
|
||||
close(pipe_fd[0]);
|
||||
close(pipe_fd[1]);
|
||||
return -1;
|
||||
}
|
||||
/* parent */
|
||||
close(pipe_fd[0]);
|
||||
write(pipe_fd[1], password, strlen(password));
|
||||
write(pipe_fd[1], "\n", 1);
|
||||
close(pipe_fd[1]);
|
||||
|
||||
while ((wpid = wait(&status)) != pid) {
|
||||
if (wpid == -1)
|
||||
return -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
@@ -1311,7 +1311,7 @@
|
||||
|
||||
This means that fred's password is valid, it was last changed on
|
||||
03/04/96, it can be changed at any time, it expires after 60 days,
|
||||
fred will not be warned, and and the account won't be disabled when
|
||||
fred will not be warned, and the account won't be disabled when
|
||||
the password expires.
|
||||
|
||||
This simply means that if fred logs in after the password expires, he
|
||||
@@ -1487,7 +1487,7 @@
|
||||
|
||||
If a user logs into a line that is listed in /etc/dialups, and his
|
||||
shell is listed in the file /etc/d_passwd he will be allowed access
|
||||
only by suppling the correct password.
|
||||
only by supplying the correct password.
|
||||
|
||||
Another useful purpose for using dial-up passwords might be to setup a
|
||||
line that only allows a certain type of connect (perhaps a PPP or UUCP
|
||||
|
||||
@@ -63,4 +63,3 @@ To completely disable limits for a user, a single dash (-) will do.
|
||||
Also, please note that all limit settings are set PER LOGIN. They are
|
||||
not global, nor are they permanent. Perhaps global limits will come, but
|
||||
for now this will have to do ;)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# This is the current (still incomplete) list of platforms this
|
||||
# package has been verified to work on. Additions (preferably
|
||||
# in the format as described below) are welcome. Thanks!
|
||||
#
|
||||
#
|
||||
# V: last version reported to work
|
||||
# H: host type
|
||||
# L: Linux libc version
|
||||
|
||||
4
doc/README.skey
Normal file
4
doc/README.skey
Normal file
@@ -0,0 +1,4 @@
|
||||
# S/Key support
|
||||
shadow-utils can be built with S/Key support using the S/Key package from:
|
||||
* http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libskey/ or
|
||||
* https://gentoo.osuosl.org/distfiles/skey-1.1.5.tar.bz2
|
||||
@@ -26,7 +26,6 @@ New ideas to add to this list are welcome, too. --marekm
|
||||
- vipw: check password files for errors after editing
|
||||
- add "maximum time users allowed to stay logged in" limit option to logoutd
|
||||
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
|
||||
- better utmpx support (logoutd, ...)
|
||||
- better OPIE support (report number of logins left, etc.)
|
||||
- new option for /etc/suauth: don't load user's environment (force "su -")
|
||||
suggested by Ulisses Alonso Camaro
|
||||
@@ -37,4 +36,3 @@ New ideas to add to this list are welcome, too. --marekm
|
||||
per-user configuration, to be executed with run-parts. Some hooks should
|
||||
be executed at package install time for existing users, likewise for
|
||||
package removal and possibly modification. (Debian Bug#36019)
|
||||
|
||||
|
||||
73
doc/contributions/build_install.md
Normal file
73
doc/contributions/build_install.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Build & install
|
||||
|
||||
The following page explains how to build and install the shadow project.
|
||||
Additional information on how to do this in a container environment is provided
|
||||
at the end of the page.
|
||||
|
||||
## Local
|
||||
|
||||
### Dependency installation
|
||||
|
||||
This projects depends on other software packages that need to be installed
|
||||
before building it. We recommend using the dependency installation commands
|
||||
provided by the distributions to install them. Some examples below.
|
||||
|
||||
Debian:
|
||||
```
|
||||
apt-get build-dep shadow
|
||||
```
|
||||
|
||||
Fedora:
|
||||
```
|
||||
dnf builddep shadow-utils
|
||||
```
|
||||
|
||||
An alternative would be to take a look at the CI workflow [file](../../.github/workflows/runner.yml)
|
||||
and get the package names from there. This has the advantage that it
|
||||
also includes new dependencies needed for the development version
|
||||
which might have not been present in the last release.
|
||||
|
||||
### Configure
|
||||
|
||||
The first step is to configure it. You can use the
|
||||
`autogen.sh` script provided by the project. Example:
|
||||
|
||||
```
|
||||
./autogen.sh --without-selinux --enable-man --with-yescrypt
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
The next step is to build the project:
|
||||
|
||||
```
|
||||
make -j4
|
||||
```
|
||||
|
||||
### Install
|
||||
|
||||
The last step is to install it. We recommend avoiding this step and using a
|
||||
disposable system like a VM or a container instead.
|
||||
|
||||
```
|
||||
make install
|
||||
```
|
||||
|
||||
## Containers
|
||||
|
||||
Alternatively, you can use any of the preconfigured container images builders
|
||||
to build and install shadow.
|
||||
|
||||
You can either generate a single image by running the following command from
|
||||
the root folder of the project (i.e. Alpine):
|
||||
|
||||
```
|
||||
docker build -f share/containers/alpine.dockerfile . --output build-out/alpine
|
||||
```
|
||||
|
||||
Or generate all of the images with the `container-build.sh` script, as if you
|
||||
were running some of the CI checks locally:
|
||||
|
||||
```
|
||||
share/container-build.sh
|
||||
```
|
||||
25
doc/contributions/ci.md
Normal file
25
doc/contributions/ci.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Continuous Integration (CI)
|
||||
|
||||
Shadow runs a CI workflow every time a pull-request (PR) is updated. This
|
||||
workflow contains several checks to assure the quality of the project, and
|
||||
only pull-requests with green results are merged.
|
||||
|
||||
## Build & install
|
||||
|
||||
The project is built & installed on Ubuntu, Alpine, Debian and Fedora. The last
|
||||
three distributions are built & installed on containers, and the workflow can
|
||||
be triggered locally by following the instructions specified in the
|
||||
[Build & install](build_install.md#containers) page.
|
||||
|
||||
## System tests
|
||||
|
||||
The project is tested on Ubuntu. For that purpose it is built & installed in
|
||||
this distribution in a VM. You can run this step locally by following the
|
||||
instructions provided in the [Tests](tests.md#system-tests) page.
|
||||
|
||||
## Static code analysis
|
||||
|
||||
C and shell static code analysis is also executed. For that purpose
|
||||
[CodeQL](https://codeql.github.com/) and
|
||||
[Differential ShellCheck](https://github.com/marketplace/actions/differential-shellcheck)
|
||||
are used.
|
||||
12
doc/contributions/coding_style.md
Normal file
12
doc/contributions/coding_style.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Coding style
|
||||
|
||||
* For a general guidance refer to the
|
||||
[Linux kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html)
|
||||
|
||||
* Patches that change the existing coding style are not welcome, as they make
|
||||
downstream porting harder for the distributions
|
||||
|
||||
## Indentation
|
||||
|
||||
Tabs are preferred over spaces for indentation. Loading the `.editorconfig`
|
||||
file in your preferred IDE may help you configure it.
|
||||
77
doc/contributions/introduction.md
Normal file
77
doc/contributions/introduction.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Introduction
|
||||
|
||||
## Git and Github
|
||||
|
||||
We recommend you to get familiar with the
|
||||
[git](https://guides.github.com/introduction/git-handbook) and
|
||||
[Github](https://guides.github.com) workflows before posting any changes.
|
||||
|
||||
### Set up in a nut shell
|
||||
|
||||
The following steps describe the process in a nut shell to provide you a basic
|
||||
template:
|
||||
|
||||
* Create an account on [GitHub](https://github.com)
|
||||
* Fork the [shadow repository](https://github.com/shadow-maint/shadow)
|
||||
* Clone the shadow repository
|
||||
|
||||
```
|
||||
git clone https://github.com/shadow-maint/shadow.git
|
||||
```
|
||||
|
||||
* Add your fork as an extra remote
|
||||
|
||||
```
|
||||
git remote add $ghusername git@github.com:$ghusername/shadow.git
|
||||
```
|
||||
|
||||
* Setup your name contact e-mail that you want to use for the development
|
||||
|
||||
```
|
||||
git config user.name "John Smith"
|
||||
git config user.email "john.smith@home.com"
|
||||
```
|
||||
|
||||
**Note**: this will setup the user information only for this repository. You
|
||||
can also add `--global` switch to the `git config` command to setup these
|
||||
options globally and thus making them available in every git repository.
|
||||
|
||||
* Create a working branch
|
||||
|
||||
```
|
||||
git checkout -b my-changes
|
||||
```
|
||||
|
||||
* Commit changes
|
||||
|
||||
```
|
||||
vim change-what-you-need
|
||||
git commit -s
|
||||
```
|
||||
|
||||
Check
|
||||
[the kernel patches guide](https://www.kernel.org/doc/html/v4.14/process/submitting-patches.html#describe-your-changes)
|
||||
to get an idea on how to write a good commit message.
|
||||
|
||||
* Push your changes to your GitHub repository
|
||||
|
||||
```
|
||||
git push $ghusername my-changes --force
|
||||
```
|
||||
|
||||
* Open a Pull Request against shadow project by clicking on the link provided
|
||||
in the output of the previous step
|
||||
|
||||
* Make sure that all Continuous Integration checks are green and wait review
|
||||
|
||||
## Internal guidelines
|
||||
|
||||
Additionally, you should also check the following internal guidelines to
|
||||
understand the project's development model:
|
||||
|
||||
* [Build & install](build_install.md)
|
||||
* [Coding style](coding_style.md)
|
||||
* [Tests](tests.md)
|
||||
* [Continuous Integration](CI.md)
|
||||
* [Releases](releases.md)
|
||||
* [License](license.md)
|
||||
10
doc/contributions/license.md
Normal file
10
doc/contributions/license.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# License
|
||||
|
||||
All new source code committed to the shadow project is assumed to be made
|
||||
available under the [BSD-3-Clause](../../COPYING) license unless the submitter
|
||||
specifies another license at that time. The shadow maintainers reserve the
|
||||
right to refuse a submission if the license is deemed incompatible with the
|
||||
goals of the project.
|
||||
|
||||
**Note**: old code may be made available under another license, check the
|
||||
license tag for each file to get additional information.
|
||||
7
doc/contributions/releases.md
Normal file
7
doc/contributions/releases.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Releases
|
||||
|
||||
The shadow project doesn't follow any specific timeline to release new software
|
||||
versions. Usually, they are released when a major milestone is finished.
|
||||
|
||||
Released source code, alongside the release notes, are provided in the
|
||||
[release Github page](https://github.com/shadow-maint/shadow/releases).
|
||||
18
doc/contributions/tests.md
Normal file
18
doc/contributions/tests.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Tests
|
||||
|
||||
Currently, shadow only provides system tests.
|
||||
|
||||
## System tests
|
||||
|
||||
These type of tests are written in shell. Unfortunately, the testing framework
|
||||
is tightly coupled to the Ubuntu distribution and it can only be run in this
|
||||
distribution. Besides, if anything fails during the execution the system can
|
||||
be left in an unstable state. Taking that into account you shouldn't run this
|
||||
workflow in your host machine, we recommend to use a disposable system like a
|
||||
VM or a container instead.
|
||||
|
||||
You can execute system tests by running:
|
||||
|
||||
```
|
||||
cd tests && ./run_all`.
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
<HEAD>
|
||||
<title>shadow - Welcome</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2> Welcome!</h2>
|
||||
<p> This is the shadow tool suite home page. </p>
|
||||
|
||||
<p>
|
||||
You can find releases <a href="https://github.com/shadow-maint/shadow/releases">here</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Raise issues, request features, and report bugs <a href="https://github.com/shadow-maint/shadow/issues">here</a>.
|
||||
</p>
|
||||
</body>
|
||||
@@ -20,4 +20,4 @@ EXTRA_DIST = \
|
||||
$(sysconf_DATA) \
|
||||
$(default_DATA)
|
||||
|
||||
SUBDIRS = pam.d
|
||||
SUBDIRS = pam.d shadow-maint
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# $Id$
|
||||
#
|
||||
# Login access control table.
|
||||
#
|
||||
#
|
||||
# When someone logs in, the table is scanned for the first entry that
|
||||
# matches the (user, host) combination, or, in case of non-networked
|
||||
# logins, the first entry that matches the (user, tty) combination. The
|
||||
# permissions field of that table entry determines whether the login will
|
||||
# permissions field of that table entry determines whether the login will
|
||||
# be accepted or refused.
|
||||
#
|
||||
#
|
||||
# Format of the login access control table is three fields separated by a
|
||||
# ":" character:
|
||||
#
|
||||
#
|
||||
# permission : users : origins
|
||||
#
|
||||
#
|
||||
# The first field should be a "+" (access granted) or "-" (access denied)
|
||||
# character.
|
||||
# character.
|
||||
#
|
||||
# The second field should be a list of one or more login names, group
|
||||
# names, or ALL (always matches). A pattern of the form user@host is
|
||||
@@ -37,7 +37,7 @@
|
||||
# listed: the program does not look at a user's primary group id value.
|
||||
#
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# Disallow console logins to all but a few accounts.
|
||||
#
|
||||
#-:ALL EXCEPT wheel shutdown sync:console
|
||||
|
||||
@@ -465,7 +465,6 @@ USERGROUPS_ENAB yes
|
||||
# Set to "yes" to prevent for all accounts
|
||||
# Set to "superuser" to prevent for UID 0 / root (default)
|
||||
# Set to "no" to not prevent for any account (dangerous, historical default)
|
||||
|
||||
PREVENT_NO_AUTH superuser
|
||||
|
||||
#
|
||||
|
||||
@@ -4,8 +4,8 @@ auth include system-auth
|
||||
account required pam_nologin.so
|
||||
account include system-auth
|
||||
password include system-auth
|
||||
session required pam_selinux.so close
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
session include system-auth
|
||||
session required pam_loginuid.so
|
||||
session optional pam_console.so
|
||||
session required pam_selinux.so open
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
|
||||
@@ -7,7 +7,7 @@ auth required pam_wheel.so use_uid
|
||||
auth include system-auth
|
||||
account include system-auth
|
||||
password include system-auth
|
||||
session required pam_selinux.so close
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
session include system-auth
|
||||
session required pam_selinux.so open multiple
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
session optional pam_xauth.so
|
||||
|
||||
5
etc/shadow-maint/Makefile.am
Normal file
5
etc/shadow-maint/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
shadowmaint_files = \
|
||||
groupdel-pre.d/01-kill_group_procs.sh \
|
||||
userdel-pre.d/01-kill_user_procs.sh
|
||||
|
||||
EXTRA_DIST = $(shadowmaint_files)
|
||||
26
etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh
Normal file
26
etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
GROUPID=`awk -F: '$1 == "'"${SUBJECT}"'" { print $3 }' /etc/group`
|
||||
|
||||
if [ "${GROUPID}" = "" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for status in /proc/*/status; do
|
||||
# either this isn't a process or its already dead since expanding the list
|
||||
[ -f "$status" ] || continue
|
||||
|
||||
tbuf=${status%/status}
|
||||
pid=${tbuf#/proc/}
|
||||
case "$pid" in
|
||||
"$$") continue;;
|
||||
[0-9]*) :;;
|
||||
*) continue
|
||||
esac
|
||||
|
||||
grep -q '^Groups:.*\b'"${GROUPID}"'\b.*' "/proc/$pid/status" || continue
|
||||
|
||||
kill -9 "$pid" || echo "cannot kill $pid" 1>&2
|
||||
done
|
||||
|
||||
31
etc/shadow-maint/userdel-pre.d/01-kill_user_procs.sh
Executable file
31
etc/shadow-maint/userdel-pre.d/01-kill_user_procs.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# Check user exists, and if so, send sigkill to processes that the user owns
|
||||
|
||||
ps -eo user >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
RUNNING=`ps -eo user | grep -Fx "$SUBJECT" | wc -l`
|
||||
# if the user does not exist, RUNNING will be 0
|
||||
if [ "${RUNNING}x" = "0x" ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# If there is no ps -eo, traverse the process directly.
|
||||
|
||||
ls -1 /proc | while IFS= read -r PROC; do
|
||||
echo "$PROC" | grep -E '^[0-9]+$' >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -d "/proc/${PROC}" ]; then
|
||||
USR=`stat -c "%U" /proc/${PROC}`
|
||||
if [ "${USR}" = "${SUBJECT}" ]; then
|
||||
echo "Killing ${SUBJECT} owned ${PROC}"
|
||||
kill -9 "${PROC}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
135
lib/Makefile.am
135
lib/Makefile.am
@@ -1,56 +1,121 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.0 foreign
|
||||
|
||||
DEFS =
|
||||
DEFS =
|
||||
|
||||
noinst_LTLIBRARIES = libshadow.la
|
||||
|
||||
if USE_PAM
|
||||
LIBCRYPT_PAM = $(LIBCRYPT)
|
||||
else
|
||||
LIBCRYPT_PAM =
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS)
|
||||
|
||||
libshadow_la_CPPFLAGS = $(ECONF_CPPFLAGS)
|
||||
if HAVE_VENDORDIR
|
||||
libshadow_la_CPPFLAGS += -DVENDORDIR=\"$(VENDORDIR)\"
|
||||
endif
|
||||
|
||||
libshadow_la_CPPFLAGS += -I$(top_srcdir)
|
||||
libshadow_la_CFLAGS = $(LIBBSD_CFLAGS) $(LIBCRYPT_PAM) $(LIBSYSTEMD)
|
||||
|
||||
libshadow_la_SOURCES = \
|
||||
addgrps.c \
|
||||
age.c \
|
||||
agetpass.c \
|
||||
alloc.c \
|
||||
alloc.h \
|
||||
audit_help.c \
|
||||
basename.c \
|
||||
bit.c \
|
||||
bit.h \
|
||||
chkname.c \
|
||||
chkname.h \
|
||||
chowndir.c \
|
||||
chowntty.c \
|
||||
cleanup.c \
|
||||
cleanup_group.c \
|
||||
cleanup_user.c \
|
||||
commonio.c \
|
||||
commonio.h \
|
||||
console.c \
|
||||
copydir.c \
|
||||
csrand.c \
|
||||
date_to_str.c \
|
||||
defines.h \
|
||||
encrypt.c \
|
||||
entry.c \
|
||||
env.c \
|
||||
exitcodes.h \
|
||||
faillog.h \
|
||||
failure.c \
|
||||
failure.h \
|
||||
fields.c \
|
||||
find_new_gid.c \
|
||||
find_new_uid.c \
|
||||
find_new_sub_gids.c \
|
||||
find_new_sub_uids.c \
|
||||
fputsx.c \
|
||||
getdef.c \
|
||||
getdef.h \
|
||||
get_gid.c \
|
||||
getlong.c \
|
||||
get_pid.c \
|
||||
get_uid.c \
|
||||
getdate.h \
|
||||
getdate.y \
|
||||
getdef.c \
|
||||
getdef.h \
|
||||
getlong.c \
|
||||
getgr_nam_gid.c \
|
||||
getrange.c \
|
||||
gettime.c \
|
||||
getulong.c \
|
||||
groupio.c \
|
||||
groupmem.c \
|
||||
groupio.h \
|
||||
gshadow.c \
|
||||
hushed.c \
|
||||
idmapping.h \
|
||||
idmapping.c \
|
||||
isexpired.c \
|
||||
limits.c \
|
||||
list.c \
|
||||
lockpw.c \
|
||||
loginprompt.c \
|
||||
mail.c \
|
||||
mempcpy.c \
|
||||
mempcpy.h \
|
||||
motd.c \
|
||||
myname.c \
|
||||
nss.c \
|
||||
nscd.c \
|
||||
nscd.h \
|
||||
sssd.c \
|
||||
sssd.h \
|
||||
obscure.c \
|
||||
pam_defs.h \
|
||||
pam_pass.c \
|
||||
pam_pass_non_interactive.c \
|
||||
port.c \
|
||||
port.h \
|
||||
prefix_flag.c \
|
||||
prototypes.h \
|
||||
pwauth.c \
|
||||
pwauth.h \
|
||||
pwio.c \
|
||||
pwio.h \
|
||||
pwd_init.c \
|
||||
pwd2spwd.c \
|
||||
pwdcheck.c \
|
||||
pwmem.c \
|
||||
remove_tree.c \
|
||||
rlogin.c \
|
||||
root_flag.c \
|
||||
run_part.h \
|
||||
run_part.c \
|
||||
subordinateio.h \
|
||||
subordinateio.c \
|
||||
salt.c \
|
||||
selinux.c \
|
||||
semanage.c \
|
||||
setugid.c \
|
||||
setupenv.c \
|
||||
sgetgrent.c \
|
||||
sgetpwent.c \
|
||||
sgetspent.c \
|
||||
@@ -59,14 +124,63 @@ libshadow_la_SOURCES = \
|
||||
shadow.c \
|
||||
shadowio.c \
|
||||
shadowio.h \
|
||||
shadowlog.c \
|
||||
shadowlog.h \
|
||||
shadowlog_internal.h \
|
||||
shadowmem.c \
|
||||
shell.c \
|
||||
spawn.c \
|
||||
utent.c
|
||||
sssd.c \
|
||||
sssd.h \
|
||||
stpecpy.c \
|
||||
stpecpy.h \
|
||||
stpeprintf.c \
|
||||
stpeprintf.h \
|
||||
strtoday.c \
|
||||
sub.c \
|
||||
subordinateio.h \
|
||||
subordinateio.c \
|
||||
sulog.c \
|
||||
ttytype.c \
|
||||
tz.c \
|
||||
ulimit.c \
|
||||
user_busy.c \
|
||||
valid.c \
|
||||
write_full.c \
|
||||
xgetpwnam.c \
|
||||
xprefix_getpwnam.c \
|
||||
xgetpwuid.c \
|
||||
xgetgrnam.c \
|
||||
xgetgrgid.c \
|
||||
xgetspnam.c \
|
||||
yesno.c
|
||||
|
||||
if WITH_TCB
|
||||
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
|
||||
endif
|
||||
|
||||
if WITH_BTRFS
|
||||
libshadow_la_SOURCES += btrfs.c
|
||||
endif
|
||||
|
||||
if ENABLE_LASTLOG
|
||||
libshadow_la_SOURCES += log.c
|
||||
endif
|
||||
|
||||
if ENABLE_LOGIND
|
||||
libshadow_la_SOURCES += logind.c
|
||||
else
|
||||
libshadow_la_SOURCES += utmp.c
|
||||
endif
|
||||
|
||||
if !WITH_LIBBSD
|
||||
libshadow_la_SOURCES += \
|
||||
freezero.h \
|
||||
freezero.c \
|
||||
readpassphrase.h \
|
||||
readpassphrase.c
|
||||
endif
|
||||
|
||||
# These files are unneeded for some reason, listed in
|
||||
# order of appearance:
|
||||
#
|
||||
@@ -74,4 +188,5 @@ endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
.indent.pro \
|
||||
gshadow_.h
|
||||
gshadow_.h \
|
||||
xgetXXbyYY.c
|
||||
|
||||
114
lib/addgrps.c
Normal file
114
lib/addgrps.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#define SEP ",:"
|
||||
/*
|
||||
* Add groups with names from LIST (separated by commas or colons)
|
||||
* to the supplementary group set. Silently ignore groups which are
|
||||
* already there. Warning: uses strtok().
|
||||
*/
|
||||
int add_groups (const char *list)
|
||||
{
|
||||
GETGROUPS_T *grouplist;
|
||||
size_t i;
|
||||
int ngroups;
|
||||
bool added;
|
||||
char *token;
|
||||
char buf[1024];
|
||||
int ret;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
if (strlen (list) >= sizeof (buf)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
strcpy (buf, list);
|
||||
|
||||
i = 16;
|
||||
for (;;) {
|
||||
grouplist = MALLOC(i, GETGROUPS_T);
|
||||
if (NULL == grouplist) {
|
||||
return -1;
|
||||
}
|
||||
ngroups = getgroups (i, grouplist);
|
||||
if ( ( (-1 == ngroups)
|
||||
&& (EINVAL != errno))
|
||||
|| (i > (size_t)ngroups)) {
|
||||
/* Unexpected failure of getgroups or successful
|
||||
* reception of the groups */
|
||||
break;
|
||||
}
|
||||
/* not enough room, so try allocating a larger buffer */
|
||||
free (grouplist);
|
||||
i *= 2;
|
||||
}
|
||||
if (ngroups < 0) {
|
||||
free (grouplist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
added = false;
|
||||
for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) {
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam (token); /* local, no need for xgetgrnam */
|
||||
if (NULL == grp) {
|
||||
fprintf (shadow_logfd, _("Warning: unknown group %s\n"),
|
||||
token);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
|
||||
|
||||
if (i < (size_t)ngroups) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
|
||||
fputs (_("Warning: too many groups\n"), shadow_logfd);
|
||||
break;
|
||||
}
|
||||
grouplist = REALLOCF(grouplist, (size_t) ngroups + 1, GETGROUPS_T);
|
||||
if (grouplist == NULL) {
|
||||
return -1;
|
||||
}
|
||||
grouplist[ngroups] = grp->gr_gid;
|
||||
ngroups++;
|
||||
added = true;
|
||||
}
|
||||
|
||||
if (added) {
|
||||
ret = setgroups (ngroups, grouplist);
|
||||
free (grouplist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
free (grouplist);
|
||||
return 0;
|
||||
}
|
||||
#else /* HAVE_SETGROUPS && !USE_PAM */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* HAVE_SETGROUPS && !USE_PAM */
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
|
||||
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2008 - 2009, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -135,7 +112,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
||||
_exit (126);
|
||||
}
|
||||
|
||||
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
|
||||
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) NULL);
|
||||
err = errno;
|
||||
perror ("Can't execute " PASSWD_PROGRAM);
|
||||
_exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
||||
@@ -162,7 +139,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
||||
|
||||
void agecheck (/*@null@*/const struct spwd *sp)
|
||||
{
|
||||
long now = (long) time ((time_t *) 0) / SCALE;
|
||||
long now = time(NULL) / SCALE;
|
||||
long remain;
|
||||
|
||||
if (NULL == sp) {
|
||||
134
lib/agetpass.c
Normal file
134
lib/agetpass.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <readpassphrase.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#if WITH_LIBBSD == 0
|
||||
#include "freezero.h"
|
||||
#endif /* WITH_LIBBSD */
|
||||
|
||||
|
||||
#if !defined(PASS_MAX)
|
||||
#define PASS_MAX BUFSIZ - 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* SYNOPSIS
|
||||
* [[gnu::malloc(erase_pass)]]
|
||||
* char *agetpass(const char *prompt);
|
||||
*
|
||||
* void erase_pass(char *pass);
|
||||
*
|
||||
* ARGUMENTS
|
||||
* agetpass()
|
||||
* prompt String to be printed before reading a password.
|
||||
*
|
||||
* erase_pass()
|
||||
* pass password previously returned by agetpass().
|
||||
*
|
||||
* DESCRIPTION
|
||||
* agetpass()
|
||||
* This function is very similar to getpass(3). It has several
|
||||
* advantages compared to getpass(3):
|
||||
*
|
||||
* - Instead of using a static buffer, agetpass() allocates memory
|
||||
* through malloc(3). This makes the function thread-safe, and
|
||||
* also reduces the visibility of the buffer.
|
||||
*
|
||||
* - agetpass() doesn't reallocate internally. Some
|
||||
* implementations of getpass(3), such as glibc, do that, as a
|
||||
* consequence of calling getline(3). That's a bug in glibc,
|
||||
* which allows leaking prefixes of passwords in freed memory.
|
||||
*
|
||||
* - agetpass() doesn't overrun the output buffer. If the input
|
||||
* password is too long, it simply fails. Some implementations
|
||||
* of getpass(3), share the same bug that gets(3) has.
|
||||
*
|
||||
* As soon as possible, the password obtained from agetpass() be
|
||||
* erased by calling erase_pass(), to avoid possibly leaking the
|
||||
* password.
|
||||
*
|
||||
* erase_pass()
|
||||
* This function first clears the password, by calling
|
||||
* explicit_bzero(3) (or an equivalent call), and then frees the
|
||||
* allocated memory by calling free(3).
|
||||
*
|
||||
* NULL is a valid input pointer, and in such a case, this call is
|
||||
* a no-op.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* agetpass() returns a newly allocated buffer containing the
|
||||
* password on success. On error, errno is set to indicate the
|
||||
* error, and NULL is returned.
|
||||
*
|
||||
* ERRORS
|
||||
* agetpass()
|
||||
* This function may fail for any errors that malloc(3) or
|
||||
* readpassphrase(3) may fail, and in addition it may fail for the
|
||||
* following errors:
|
||||
*
|
||||
* ENOBUFS
|
||||
* The input password was longer than PASS_MAX.
|
||||
*
|
||||
* CAVEATS
|
||||
* If a password is passed twice to erase_pass(), the behavior is
|
||||
* undefined.
|
||||
*/
|
||||
|
||||
|
||||
char *
|
||||
agetpass(const char *prompt)
|
||||
{
|
||||
char *pass;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* Since we want to support passwords upto PASS_MAX, we need
|
||||
* PASS_MAX bytes for the password itself, and one more byte for
|
||||
* the terminating '\0'. We also want to detect truncation, and
|
||||
* readpassphrase(3) doesn't detect it, so we need some trick.
|
||||
* Let's add one more byte, and if the password uses it, it
|
||||
* means the introduced password was longer than PASS_MAX.
|
||||
*/
|
||||
pass = MALLOC(PASS_MAX + 2, char);
|
||||
if (pass == NULL)
|
||||
return NULL;
|
||||
|
||||
if (readpassphrase(prompt, pass, PASS_MAX + 2, RPP_REQUIRE_TTY) == NULL)
|
||||
goto fail;
|
||||
|
||||
len = strlen(pass);
|
||||
if (len == PASS_MAX + 1) {
|
||||
errno = ENOBUFS;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return pass;
|
||||
|
||||
fail:
|
||||
freezero(pass, PASS_MAX + 2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
erase_pass(char *pass)
|
||||
{
|
||||
freezero(pass, PASS_MAX + 2);
|
||||
}
|
||||
73
lib/alloc.c
Normal file
73
lib/alloc.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
* SPDX-FileCopyrightText: 2023 , Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* Replacements for malloc and strdup with error checking. Too trivial
|
||||
to be worth copyrighting :-). I did that because a lot of code used
|
||||
malloc and strdup without checking for NULL pointer, and I like some
|
||||
message better than a core dump... --marekm
|
||||
|
||||
Yeh, but. Remember that bailing out might leave the system in some
|
||||
bizarre state. You really want to put in error checking, then add
|
||||
some back-out failure recovery code. -- jfh */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "alloc.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
extern inline void *xmalloc(size_t size);
|
||||
extern inline void *xmallocarray(size_t nmemb, size_t size);
|
||||
extern inline void *mallocarray(size_t nmemb, size_t size);
|
||||
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
extern inline char *xstrdup(const char *str);
|
||||
|
||||
|
||||
void *
|
||||
xcalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = calloc(nmemb, size);
|
||||
if (p == NULL)
|
||||
goto x;
|
||||
|
||||
return p;
|
||||
|
||||
x:
|
||||
fprintf(log_get_logfd(), _("%s: %s\n"),
|
||||
log_get_progname(), strerror(errno));
|
||||
exit(13);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
xreallocarray(void *p, size_t nmemb, size_t size)
|
||||
{
|
||||
p = reallocarrayf(p, nmemb, size);
|
||||
if (p == NULL)
|
||||
goto x;
|
||||
|
||||
return p;
|
||||
|
||||
x:
|
||||
fprintf(log_get_logfd(), _("%s: %s\n"),
|
||||
log_get_progname(), strerror(errno));
|
||||
exit(13);
|
||||
}
|
||||
115
lib/alloc.h
Normal file
115
lib/alloc.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
|
||||
#define SHADOW_INCLUDE_LIB_MALLOC_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
|
||||
#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
|
||||
#define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type)))
|
||||
#define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
|
||||
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
|
||||
|
||||
#define REALLOC(ptr, n, type) \
|
||||
({ \
|
||||
__auto_type p_ = (ptr); \
|
||||
\
|
||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
||||
\
|
||||
(type *) reallocarray(p_, n, sizeof(type)); \
|
||||
})
|
||||
|
||||
#define REALLOCF(ptr, n, type) \
|
||||
({ \
|
||||
__auto_type p_ = (ptr); \
|
||||
\
|
||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
||||
\
|
||||
(type *) reallocarrayf(p_, n, sizeof(type)); \
|
||||
})
|
||||
|
||||
#define XREALLOC(ptr, n, type) \
|
||||
({ \
|
||||
__auto_type p_ = (ptr); \
|
||||
\
|
||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
||||
\
|
||||
(type *) xreallocarray(p_, n, sizeof(type)); \
|
||||
})
|
||||
|
||||
|
||||
ATTR_MALLOC(free)
|
||||
inline void *xmalloc(size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *xmallocarray(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *mallocarray(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline char *xstrdup(const char *str);
|
||||
|
||||
ATTR_MALLOC(free)
|
||||
void *xcalloc(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
void *xreallocarray(void *p, size_t nmemb, size_t size);
|
||||
|
||||
|
||||
inline void *
|
||||
xmalloc(size_t size)
|
||||
{
|
||||
return xmallocarray(1, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
xmallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
return xreallocarray(NULL, nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
mallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
return reallocarray(NULL, nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
reallocarrayf(void *p, size_t nmemb, size_t size)
|
||||
{
|
||||
void *q;
|
||||
|
||||
q = reallocarray(p, nmemb, size);
|
||||
|
||||
/* realloc(p, 0) is equivalent to free(p); avoid double free. */
|
||||
if (q == NULL && nmemb != 0 && size != 0)
|
||||
free(p);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
inline char *
|
||||
xstrdup(const char *str)
|
||||
{
|
||||
return strcpy(XMALLOC(strlen(str) + 1, char), str);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
87
lib/audit_help.c
Normal file
87
lib/audit_help.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2005 , Red Hat, Inc.
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Audit helper functions used throughout shadow
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
#include <libaudit.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
int audit_fd;
|
||||
|
||||
void audit_help_open (void)
|
||||
{
|
||||
audit_fd = audit_open ();
|
||||
if (audit_fd < 0) {
|
||||
/* You get these only when the kernel doesn't have
|
||||
* audit compiled in. */
|
||||
if ( (errno == EINVAL)
|
||||
|| (errno == EPROTONOSUPPORT)
|
||||
|| (errno == EAFNOSUPPORT)) {
|
||||
return;
|
||||
}
|
||||
(void) fputs (_("Cannot open audit interface - aborting.\n"),
|
||||
log_get_logfd());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will log a message to the audit system using a predefined
|
||||
* message format. Parameter usage is as follows:
|
||||
*
|
||||
* type - type of message: AUDIT_USER_CHAUTHTOK for changing any account
|
||||
* attributes.
|
||||
* pgname - program's name
|
||||
* op - operation. "adding user", "changing finger info", "deleting group"
|
||||
* name - user's account or group name. If not available use NULL.
|
||||
* id - uid or gid that the operation is being performed on. This is used
|
||||
* only when user is NULL.
|
||||
*/
|
||||
void audit_logger (int type, unused const char *pgname, const char *op,
|
||||
const char *name, unsigned int id,
|
||||
shadow_audit_result result)
|
||||
{
|
||||
if (audit_fd < 0) {
|
||||
return;
|
||||
} else {
|
||||
audit_log_acct_message (audit_fd, type, NULL, op, name, id,
|
||||
NULL, NULL, NULL, result);
|
||||
}
|
||||
}
|
||||
|
||||
void audit_logger_message (const char *message, shadow_audit_result result)
|
||||
{
|
||||
if (audit_fd < 0) {
|
||||
return;
|
||||
} else {
|
||||
audit_log_user_message (audit_fd,
|
||||
AUDIT_USYS_CONFIG,
|
||||
message,
|
||||
NULL, /* hostname */
|
||||
NULL, /* addr */
|
||||
NULL, /* tty */
|
||||
result);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* WITH_AUDIT */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* WITH_AUDIT */
|
||||
|
||||
31
lib/basename.c
Normal file
31
lib/basename.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* basename.c - not worth copyrighting :-). Some versions of Linux libc
|
||||
* already have basename(), other versions don't. To avoid confusion,
|
||||
* we will not use the function from libc and use a different name here.
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*@observer@*/const char *Basename (const char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
abort ();
|
||||
}
|
||||
|
||||
char *cp = strrchr (str, '/');
|
||||
|
||||
return (NULL != cp) ? cp + 1 : str;
|
||||
}
|
||||
19
lib/bit.c
Normal file
19
lib/bit.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "bit.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
extern inline unsigned long bit_ceilul(unsigned long x);
|
||||
extern inline unsigned long bit_ceil_wrapul(unsigned long x);
|
||||
extern inline int leading_zerosul(unsigned long x);
|
||||
53
lib/bit.h
Normal file
53
lib/bit.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_BIT_H_
|
||||
#define SHADOW_INCLUDE_LIB_BIT_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#ifndef ULONG_WIDTH
|
||||
#define ULONG_WIDTH (sizeof(unsigned long) * CHAR_BIT)
|
||||
#endif
|
||||
|
||||
|
||||
inline unsigned long bit_ceilul(unsigned long x);
|
||||
inline unsigned long bit_ceil_wrapul(unsigned long x);
|
||||
inline int leading_zerosul(unsigned long x);
|
||||
|
||||
|
||||
/* stdc_bit_ceilul(3) */
|
||||
inline unsigned long
|
||||
bit_ceilul(unsigned long x)
|
||||
{
|
||||
return 1 + (ULONG_MAX >> leading_zerosul(x));
|
||||
}
|
||||
|
||||
|
||||
/* stdc_bit_ceilul(3), but wrap instead of having Undefined Behavior */
|
||||
inline unsigned long
|
||||
bit_ceil_wrapul(unsigned long x)
|
||||
{
|
||||
if (x == 0)
|
||||
return 0;
|
||||
|
||||
return bit_ceilul(x);
|
||||
}
|
||||
|
||||
/* stdc_leading_zerosul(3) */
|
||||
inline int
|
||||
leading_zerosul(unsigned long x)
|
||||
{
|
||||
return (x == 0) ? ULONG_WIDTH : __builtin_clzl(x);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -14,7 +14,7 @@ static bool path_exists(const char *p)
|
||||
|
||||
static const char *btrfs_cmd(void)
|
||||
{
|
||||
const char *btrfs_paths[] = {"/sbin/btrfs",
|
||||
const char *const btrfs_paths[] = {"/sbin/btrfs",
|
||||
"/bin/btrfs", "/usr/sbin/btrfs", "/usr/bin/btrfs", NULL};
|
||||
const char *p;
|
||||
int i;
|
||||
100
lib/chkname.c
Normal file
100
lib/chkname.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2005 - 2008, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* is_valid_user_name(), is_valid_group_name() - check the new user/group
|
||||
* name for validity;
|
||||
* return values:
|
||||
* true - OK
|
||||
* false - bad name
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
|
||||
int allow_bad_names = false;
|
||||
|
||||
static bool is_valid_name (const char *name)
|
||||
{
|
||||
if (allow_bad_names) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* User/group names must match gnu e-regex:
|
||||
* [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?
|
||||
*
|
||||
* as a non-POSIX, extension, allow "$" as the last char for
|
||||
* sake of Samba 3.x "add machine script"
|
||||
*
|
||||
* Also do not allow fully numeric names or just "." or "..".
|
||||
*/
|
||||
int numeric;
|
||||
|
||||
if ('\0' == *name ||
|
||||
('.' == *name && (('.' == name[1] && '\0' == name[2]) ||
|
||||
'\0' == name[1])) ||
|
||||
!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
(*name >= '0' && *name <= '9') ||
|
||||
*name == '_' ||
|
||||
*name == '.')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
numeric = isdigit(*name);
|
||||
|
||||
while ('\0' != *++name) {
|
||||
if (!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
(*name >= '0' && *name <= '9') ||
|
||||
*name == '_' ||
|
||||
*name == '.' ||
|
||||
*name == '-' ||
|
||||
(*name == '$' && name[1] == '\0')
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
numeric &= isdigit(*name);
|
||||
}
|
||||
|
||||
return !numeric;
|
||||
}
|
||||
|
||||
bool is_valid_user_name (const char *name)
|
||||
{
|
||||
/*
|
||||
* User names length are limited by the kernel
|
||||
*/
|
||||
if (strlen (name) > sysconf(_SC_LOGIN_NAME_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_valid_name (name);
|
||||
}
|
||||
|
||||
bool is_valid_group_name (const char *name)
|
||||
{
|
||||
/*
|
||||
* Arbitrary limit for group names.
|
||||
* HP-UX 10 limits to 16 characters
|
||||
*/
|
||||
if ( (GROUP_NAME_MAX_LENGTH > 0)
|
||||
&& (strlen (name) > GROUP_NAME_MAX_LENGTH)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_valid_name (name);
|
||||
}
|
||||
|
||||
27
lib/chkname.h
Normal file
27
lib/chkname.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
#ifndef _CHKNAME_H_
|
||||
#define _CHKNAME_H_
|
||||
|
||||
/*
|
||||
* is_valid_user_name(), is_valid_group_name() - check the new user/group
|
||||
* name for validity;
|
||||
* return values:
|
||||
* true - OK
|
||||
* false - bad name
|
||||
*/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
extern bool is_valid_user_name (const char *name);
|
||||
extern bool is_valid_group_name (const char *name);
|
||||
|
||||
#endif
|
||||
146
lib/chowndir.c
Normal file
146
lib/chowndir.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1992 - 1993, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2010 - , Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int chown_tree_at (int at_fd,
|
||||
const char *path,
|
||||
uid_t old_uid,
|
||||
uid_t new_uid,
|
||||
gid_t old_gid,
|
||||
gid_t new_gid)
|
||||
{
|
||||
DIR *dir;
|
||||
const struct dirent *ent;
|
||||
struct stat dir_sb;
|
||||
int dir_fd, rc = 0;
|
||||
|
||||
dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
|
||||
if (dir_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir = fdopendir (dir_fd);
|
||||
if (!dir) {
|
||||
(void) close (dir_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the directory and read each entry. Every entry is tested
|
||||
* to see if it is a directory, and if so this routine is called
|
||||
* recursively. If not, it is checked to see if an ownership
|
||||
* shall be changed.
|
||||
*/
|
||||
while ((ent = readdir (dir))) {
|
||||
uid_t tmpuid = (uid_t) -1;
|
||||
gid_t tmpgid = (gid_t) -1;
|
||||
struct stat ent_sb;
|
||||
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
if ( (strcmp (ent->d_name, ".") == 0)
|
||||
|| (strcmp (ent->d_name, "..") == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW);
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (S_ISDIR (ent_sb.st_mode)) {
|
||||
/*
|
||||
* Do the entire subdirectory.
|
||||
*/
|
||||
rc = chown_tree_at (dirfd(dir), ent->d_name, old_uid, new_uid, old_gid, new_gid);
|
||||
if (0 != rc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* By default, the IDs are not changed (-1).
|
||||
*
|
||||
* If the file is not owned by the user, the owner is not
|
||||
* changed.
|
||||
*
|
||||
* If the file is not group-owned by the group, the
|
||||
* group-owner is not changed.
|
||||
*/
|
||||
if (((uid_t) -1 == old_uid) || (ent_sb.st_uid == old_uid)) {
|
||||
tmpuid = new_uid;
|
||||
}
|
||||
if (((gid_t) -1 == old_gid) || (ent_sb.st_gid == old_gid)) {
|
||||
tmpgid = new_gid;
|
||||
}
|
||||
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
|
||||
rc = fchownat (dirfd(dir), ent->d_name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
|
||||
if (0 != rc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now do the root of the tree
|
||||
*/
|
||||
if ((0 == rc) && (fstat (dirfd(dir), &dir_sb) == 0)) {
|
||||
uid_t tmpuid = (uid_t) -1;
|
||||
gid_t tmpgid = (gid_t) -1;
|
||||
if (((uid_t) -1 == old_uid) || (dir_sb.st_uid == old_uid)) {
|
||||
tmpuid = new_uid;
|
||||
}
|
||||
if (((gid_t) -1 == old_gid) || (dir_sb.st_gid == old_gid)) {
|
||||
tmpgid = new_gid;
|
||||
}
|
||||
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
|
||||
rc = fchown (dirfd(dir), tmpuid, tmpgid);
|
||||
}
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
(void) closedir (dir);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* chown_tree - change ownership of files in a directory tree
|
||||
*
|
||||
* chown_dir() walks a directory tree and changes the ownership
|
||||
* of all files owned by the provided user ID.
|
||||
*
|
||||
* Only files owned (resp. group-owned) by old_uid (resp. by old_gid)
|
||||
* will have their ownership (resp. group-ownership) modified, unless
|
||||
* old_uid (resp. old_gid) is set to -1.
|
||||
*
|
||||
* new_uid and new_gid can be set to -1 to indicate that no owner or
|
||||
* group-owner shall be changed.
|
||||
*/
|
||||
int chown_tree (const char *root,
|
||||
uid_t old_uid,
|
||||
uid_t new_uid,
|
||||
gid_t old_gid,
|
||||
gid_t new_gid)
|
||||
{
|
||||
return chown_tree_at (AT_FDCWD, root, old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
79
lib/chowntty.c
Normal file
79
lib/chowntty.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* chown_tty() sets the login tty to be owned by the new user ID
|
||||
* with TTYPERM modes
|
||||
*/
|
||||
|
||||
void chown_tty (const struct passwd *info)
|
||||
{
|
||||
struct group *grent;
|
||||
gid_t gid;
|
||||
|
||||
/*
|
||||
* See if login.defs has some value configured for the port group
|
||||
* ID. Otherwise, use the user's primary group ID.
|
||||
*/
|
||||
|
||||
grent = getgr_nam_gid (getdef_str ("TTYGROUP"));
|
||||
if (NULL != grent) {
|
||||
gid = grent->gr_gid;
|
||||
gr_free (grent);
|
||||
} else {
|
||||
gid = info->pw_gid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the permissions on the TTY to be owned by the user with
|
||||
* the group as determined above.
|
||||
*/
|
||||
|
||||
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|
||||
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
|
||||
int err = errno;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
fprintf (shadow_logfd,
|
||||
_("Unable to change owner or mode of tty stdin: %s"),
|
||||
strerror (err));
|
||||
SYSLOG ((LOG_WARN,
|
||||
"unable to change owner or mode of tty stdin for user `%s': %s\n",
|
||||
info->pw_name, strerror (err)));
|
||||
if (EROFS != err) {
|
||||
closelog ();
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Please don't add code to chown /dev/vcs* to the user logging in -
|
||||
* it's a potential security hole. I wouldn't like the previous user
|
||||
* to hold the file descriptor open and watch my screen. We don't
|
||||
* have the *BSD revoke() system call yet, and vhangup() only works
|
||||
* for tty devices (which vcs* is not). --marekm
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 - 2011, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -36,6 +13,7 @@
|
||||
#include "groupio.h"
|
||||
#include "sgroupio.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* cleanup_report_add_group - Report failure to add a group to the system
|
||||
@@ -44,11 +22,11 @@
|
||||
*/
|
||||
void cleanup_report_add_group (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, Prog,
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -62,11 +40,11 @@ void cleanup_report_add_group (void *group_name)
|
||||
*/
|
||||
void cleanup_report_del_group (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_GROUP, Prog,
|
||||
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -83,7 +61,7 @@ void cleanup_report_mod_group (void *cleanup_info)
|
||||
gr_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, Prog,
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -101,7 +79,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
|
||||
sgr_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, Prog,
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -117,11 +95,11 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
|
||||
*/
|
||||
void cleanup_report_add_group_group (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, Prog,
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"adding group to /etc/group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -137,11 +115,11 @@ void cleanup_report_add_group_group (void *group_name)
|
||||
*/
|
||||
void cleanup_report_add_group_gshadow (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, Prog,
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"adding group to /etc/gshadow",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -158,13 +136,13 @@ void cleanup_report_add_group_gshadow (void *group_name)
|
||||
*/
|
||||
void cleanup_report_del_group_group (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR,
|
||||
"failed to remove group %s from %s",
|
||||
name, gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, Prog,
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"removing group from /etc/group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -181,13 +159,13 @@ void cleanup_report_del_group_group (void *group_name)
|
||||
*/
|
||||
void cleanup_report_del_group_gshadow (void *group_name)
|
||||
{
|
||||
const char *name = (const char *)group_name;
|
||||
const char *name = group_name;
|
||||
|
||||
SYSLOG ((LOG_ERR,
|
||||
"failed to remove group %s from %s",
|
||||
name, sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, Prog,
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"removing group from /etc/gshadow",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -203,9 +181,9 @@ void cleanup_report_del_group_gshadow (void *group_name)
|
||||
void cleanup_unlock_group (unused void *arg)
|
||||
{
|
||||
if (gr_unlock () == 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
Prog, gr_dbname ());
|
||||
log_get_progname(), gr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking group file",
|
||||
@@ -223,9 +201,9 @@ void cleanup_unlock_group (unused void *arg)
|
||||
void cleanup_unlock_gshadow (unused void *arg)
|
||||
{
|
||||
if (sgr_unlock () == 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
log_get_progname(), sgr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking gshadow file",
|
||||
130
lib/cleanup_user.c
Normal file
130
lib/cleanup_user.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* cleanup_report_add_user - Report failure to add a user to the system
|
||||
*
|
||||
* It should be registered when it is decided to add a user to the system.
|
||||
*/
|
||||
void cleanup_report_add_user (void *user_name)
|
||||
{
|
||||
const char *name = user_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cleanup_report_mod_passwd (void *cleanup_info)
|
||||
{
|
||||
const struct cleanup_info_mod *info;
|
||||
info = (const struct cleanup_info_mod *)cleanup_info;
|
||||
|
||||
SYSLOG ((LOG_ERR,
|
||||
"failed to change %s (%s)",
|
||||
pw_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup_report_add_user_passwd - Report failure to add a user to
|
||||
* /etc/passwd
|
||||
*
|
||||
* It should be registered when it is decided to add a user to the
|
||||
* /etc/passwd database.
|
||||
*/
|
||||
void cleanup_report_add_user_passwd (void *user_name)
|
||||
{
|
||||
const char *name = user_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
"adding user to /etc/passwd",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup_report_add_user_shadow - Report failure to add a user to
|
||||
* /etc/shadow
|
||||
*
|
||||
* It should be registered when it is decided to add a user to the
|
||||
* /etc/shadow database.
|
||||
*/
|
||||
void cleanup_report_add_user_shadow (void *user_name)
|
||||
{
|
||||
const char *name = user_name;
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
"adding user to /etc/shadow",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup_unlock_passwd - Unlock the /etc/passwd database
|
||||
*
|
||||
* It should be registered after the passwd database is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_passwd (unused void *arg)
|
||||
{
|
||||
if (pw_unlock () == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), pw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking passwd file",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup_unlock_shadow - Unlock the /etc/shadow database
|
||||
*
|
||||
* It should be registered after the shadow database is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_shadow (unused void *arg)
|
||||
{
|
||||
if (spw_unlock () == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), spw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking shadow file",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
157
lib/commonio.c
157
lib/commonio.c
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2001, Marek Michałkiewicz
|
||||
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2011, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2011, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -44,6 +21,8 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "nscd.h"
|
||||
#include "sssd.h"
|
||||
#ifdef WITH_TCB
|
||||
@@ -51,10 +30,11 @@
|
||||
#endif /* WITH_TCB */
|
||||
#include "prototypes.h"
|
||||
#include "commonio.h"
|
||||
#include "shadowlog_internal.h"
|
||||
|
||||
/* local function prototypes */
|
||||
static int lrename (const char *, const char *);
|
||||
static int check_link_count (const char *file);
|
||||
static int check_link_count (const char *file, bool log);
|
||||
static int do_lock_file (const char *file, const char *lock, bool log);
|
||||
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||
const char *name,
|
||||
@@ -87,7 +67,6 @@ int lrename (const char *old, const char *new)
|
||||
int res;
|
||||
char *r = NULL;
|
||||
|
||||
#if defined(S_ISLNK)
|
||||
#ifndef __GLIBC__
|
||||
char resolved_path[PATH_MAX];
|
||||
#endif /* !__GLIBC__ */
|
||||
@@ -104,28 +83,35 @@ int lrename (const char *old, const char *new)
|
||||
new = r;
|
||||
}
|
||||
}
|
||||
#endif /* S_ISLNK */
|
||||
|
||||
res = rename (old, new);
|
||||
|
||||
#ifdef __GLIBC__
|
||||
if (NULL != r) {
|
||||
free (r);
|
||||
}
|
||||
free (r);
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int check_link_count (const char *file)
|
||||
static int check_link_count (const char *file, bool log)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat (file, &sb) != 0) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file stat error: %s\n",
|
||||
shadow_progname, file, strerror (errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sb.st_nlink != 2) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: lock file already used (nlink: %u)\n",
|
||||
shadow_progname, file, sb.st_nlink);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -146,7 +132,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: %s\n",
|
||||
Prog, file, strerror (errno));
|
||||
shadow_progname, file, strerror (errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -154,11 +140,11 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
pid = getpid ();
|
||||
snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
|
||||
len = (ssize_t) strlen (buf) + 1;
|
||||
if (write (fd, buf, (size_t) len) != len) {
|
||||
if (write_full (fd, buf, (size_t) len) != len) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file write error: %s\n",
|
||||
Prog, file, strerror (errno));
|
||||
shadow_progname, file, strerror (errno));
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@@ -168,7 +154,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file sync error: %s\n",
|
||||
Prog, file, strerror (errno));
|
||||
shadow_progname, file, strerror (errno));
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@@ -177,12 +163,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
close (fd);
|
||||
|
||||
if (link (file, lock) == 0) {
|
||||
retval = check_link_count (file);
|
||||
if ((0==retval) && log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: lock file already used\n",
|
||||
Prog, file);
|
||||
}
|
||||
retval = check_link_count (file, log);
|
||||
unlink (file);
|
||||
return retval;
|
||||
}
|
||||
@@ -192,7 +173,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: %s\n",
|
||||
Prog, lock, strerror (errno));
|
||||
shadow_progname, lock, strerror (errno));
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@@ -204,7 +185,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: existing lock file %s without a PID\n",
|
||||
Prog, lock);
|
||||
shadow_progname, lock);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@@ -215,7 +196,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: existing lock file %s with an invalid PID '%s'\n",
|
||||
Prog, lock, buf);
|
||||
shadow_progname, lock, buf);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@@ -225,7 +206,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: lock %s already used by PID %lu\n",
|
||||
Prog, lock, (unsigned long) pid);
|
||||
shadow_progname, lock, (unsigned long) pid);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EEXIST;
|
||||
@@ -235,7 +216,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
Prog, lock, strerror (errno));
|
||||
shadow_progname, lock, strerror (errno));
|
||||
}
|
||||
unlink (file);
|
||||
return 0;
|
||||
@@ -243,17 +224,12 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
|
||||
retval = 0;
|
||||
if (link (file, lock) == 0) {
|
||||
retval = check_link_count (file);
|
||||
if ((0==retval) && log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: lock file already used\n",
|
||||
Prog, file);
|
||||
}
|
||||
retval = check_link_count (file, log);
|
||||
} else {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
Prog, lock, strerror (errno));
|
||||
shadow_progname, lock, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,25 +253,13 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
if (fchown (fileno (fp), sb->st_uid, sb->st_gid) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
#else /* !HAVE_FCHOWN */
|
||||
if (chown (name, sb->st_mode) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
#endif /* !HAVE_FCHOWN */
|
||||
|
||||
#ifdef HAVE_FCHMOD
|
||||
if (fchmod (fileno (fp), sb->st_mode & 0664) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
#else /* !HAVE_FCHMOD */
|
||||
if (chmod (name, sb->st_mode & 0664) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
#endif /* !HAVE_FCHMOD */
|
||||
|
||||
return fp;
|
||||
|
||||
fail:
|
||||
@@ -361,9 +325,7 @@ static void free_linked_list (struct commonio_db *db)
|
||||
p = db->head;
|
||||
db->head = p->next;
|
||||
|
||||
if (NULL != p->line) {
|
||||
free (p->line);
|
||||
}
|
||||
free (p->line);
|
||||
|
||||
if (NULL != p->eptr) {
|
||||
db->ops->free (p->eptr);
|
||||
@@ -402,12 +364,12 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
|
||||
}
|
||||
file_len = strlen(db->filename) + 11;/* %lu max size */
|
||||
lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
|
||||
file = (char*)malloc(file_len);
|
||||
if(file == NULL) {
|
||||
file = MALLOC(file_len, char);
|
||||
if (file == NULL) {
|
||||
goto cleanup_ENOMEM;
|
||||
}
|
||||
lock = (char*)malloc(lock_file_len);
|
||||
if(lock == NULL) {
|
||||
lock = MALLOC(lock_file_len, char);
|
||||
if (lock == NULL) {
|
||||
goto cleanup_ENOMEM;
|
||||
}
|
||||
snprintf (file, file_len, "%s.%lu",
|
||||
@@ -419,10 +381,8 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
|
||||
err = 1;
|
||||
}
|
||||
cleanup_ENOMEM:
|
||||
if(file)
|
||||
free(file);
|
||||
if(lock)
|
||||
free(lock);
|
||||
free(file);
|
||||
free(lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -448,7 +408,7 @@ int commonio_lock (struct commonio_db *db)
|
||||
if (geteuid () != 0) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: Permission denied.\n",
|
||||
Prog);
|
||||
shadow_progname);
|
||||
}
|
||||
return 0; /* failure */
|
||||
}
|
||||
@@ -483,7 +443,7 @@ int commonio_lock (struct commonio_db *db)
|
||||
/* no unnecessary retries on "permission denied" errors */
|
||||
if (geteuid () != 0) {
|
||||
(void) fprintf (shadow_logfd, "%s: Permission denied.\n",
|
||||
Prog);
|
||||
shadow_progname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -648,7 +608,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
|
||||
fd = open (db->filename,
|
||||
(db->readonly ? O_RDONLY : O_RDWR)
|
||||
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
|
||||
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC);
|
||||
saved_errno = errno;
|
||||
db->fp = NULL;
|
||||
if (fd >= 0) {
|
||||
@@ -679,22 +639,19 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do not inherit fd in spawned processes (e.g. nscd) */
|
||||
fcntl (fileno (db->fp), F_SETFD, FD_CLOEXEC);
|
||||
|
||||
buflen = BUFLEN;
|
||||
buf = (char *) malloc (buflen);
|
||||
buf = MALLOC(buflen, char);
|
||||
if (NULL == buf) {
|
||||
goto cleanup_ENOMEM;
|
||||
}
|
||||
|
||||
while (db->ops->fgets (buf, (int) buflen, db->fp) == buf) {
|
||||
while (db->ops->fgets (buf, buflen, db->fp) == buf) {
|
||||
while ( ((cp = strrchr (buf, '\n')) == NULL)
|
||||
&& (feof (db->fp) == 0)) {
|
||||
size_t len;
|
||||
|
||||
buflen += BUFLEN;
|
||||
cp = (char *) realloc (buf, buflen);
|
||||
cp = REALLOC(buf, buflen, char);
|
||||
if (NULL == cp) {
|
||||
goto cleanup_buf;
|
||||
}
|
||||
@@ -728,7 +685,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
goto cleanup_entry;
|
||||
}
|
||||
@@ -805,7 +762,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
||||
return 0;
|
||||
}
|
||||
|
||||
entries = malloc (n * sizeof (struct commonio_entry *));
|
||||
entries = MALLOC(n, struct commonio_entry *);
|
||||
if (entries == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1028,13 +985,11 @@ int commonio_close (struct commonio_db *db)
|
||||
if (fflush (db->fp) != 0) {
|
||||
errors++;
|
||||
}
|
||||
#ifdef HAVE_FSYNC
|
||||
|
||||
if (fsync (fileno (db->fp)) != 0) {
|
||||
errors++;
|
||||
}
|
||||
#else /* !HAVE_FSYNC */
|
||||
sync ();
|
||||
#endif /* !HAVE_FSYNC */
|
||||
|
||||
if (fclose (db->fp) != 0) {
|
||||
errors++;
|
||||
}
|
||||
@@ -1126,7 +1081,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
||||
return 1;
|
||||
}
|
||||
/* not found, new entry */
|
||||
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
db->ops->free (nentry);
|
||||
errno = ENOMEM;
|
||||
@@ -1163,7 +1118,7 @@ int commonio_append (struct commonio_db *db, const void *eptr)
|
||||
return 0;
|
||||
}
|
||||
/* new entry */
|
||||
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
db->ops->free (nentry);
|
||||
errno = ENOMEM;
|
||||
@@ -1224,14 +1179,14 @@ int commonio_remove (struct commonio_db *db, const char *name)
|
||||
|
||||
commonio_del_entry (db, p);
|
||||
|
||||
if (NULL != p->line) {
|
||||
free (p->line);
|
||||
}
|
||||
free (p->line);
|
||||
|
||||
if (NULL != p->eptr) {
|
||||
db->ops->free (p->eptr);
|
||||
}
|
||||
|
||||
free(p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
||||
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2010, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -146,6 +123,7 @@ extern int commonio_setname (struct commonio_db *, const char *);
|
||||
extern bool commonio_present (const struct commonio_db *db);
|
||||
extern int commonio_lock (struct commonio_db *);
|
||||
extern int commonio_lock_nowait (struct commonio_db *, bool log);
|
||||
extern int do_fcntl_lock (const char *file, bool log, short type);
|
||||
extern int commonio_open (struct commonio_db *, int);
|
||||
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
||||
extern int commonio_update (struct commonio_db *, const void *);
|
||||
|
||||
108
lib/console.c
Normal file
108
lib/console.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1991 , Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1991 , Chip Rosenthal
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
/*
|
||||
* This is now rather generic function which decides if "tty" is listed
|
||||
* under "cfgin" in config (directly or indirectly). Fallback to default if
|
||||
* something is bad.
|
||||
*/
|
||||
static bool is_listed (const char *cfgin, const char *tty, bool def)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024], *s;
|
||||
const char *cons;
|
||||
|
||||
/*
|
||||
* If the CONSOLE configuration definition isn't given,
|
||||
* fallback to default.
|
||||
*/
|
||||
|
||||
cons = getdef_str (cfgin);
|
||||
if (NULL == cons) {
|
||||
return def;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this isn't a filename, then it is a ":" delimited list of
|
||||
* console devices upon which root logins are allowed.
|
||||
*/
|
||||
|
||||
if (*cons != '/') {
|
||||
char *pbuf;
|
||||
strlcpy (buf, cons, sizeof (buf));
|
||||
pbuf = &buf[0];
|
||||
while ((s = strtok (pbuf, ":")) != NULL) {
|
||||
if (strcmp (s, tty) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pbuf = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't open the console list, then call everything a
|
||||
* console - otherwise root will never be allowed to login.
|
||||
*/
|
||||
|
||||
fp = fopen (cons, "r");
|
||||
if (NULL == fp) {
|
||||
return def;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if this tty is listed in the console file.
|
||||
*/
|
||||
|
||||
while (fgets (buf, sizeof (buf), fp) != NULL) {
|
||||
/* Remove optional trailing '\n'. */
|
||||
buf[strcspn (buf, "\n")] = '\0';
|
||||
if (strcmp (buf, tty) == 0) {
|
||||
(void) fclose (fp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This tty isn't a console.
|
||||
*/
|
||||
|
||||
(void) fclose (fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* console - return 1 if the "tty" is a console device, else 0.
|
||||
*
|
||||
* Note - we need to take extreme care here to avoid locking out root logins
|
||||
* if something goes awry. That's why we do things like call everything a
|
||||
* console if the consoles file can't be opened. Because of this, we must
|
||||
* warn the user to protect against the remove of the consoles file since
|
||||
* that would allow an unauthorized root login.
|
||||
*/
|
||||
|
||||
bool console (const char *tty)
|
||||
{
|
||||
if (strncmp (tty, "/dev/", 5) == 0) {
|
||||
tty += 5;
|
||||
}
|
||||
|
||||
return is_listed ("CONSOLE", tty, true);
|
||||
}
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2001, Marek Michałkiewicz
|
||||
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2010, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -40,6 +17,8 @@
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#ifdef WITH_SELINUX
|
||||
@@ -55,6 +34,7 @@
|
||||
#ifdef WITH_ATTR
|
||||
#include <attr/libattr.h>
|
||||
#endif /* WITH_ATTR */
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
static /*@null@*/const char *src_orig;
|
||||
@@ -69,42 +49,43 @@ struct link_name {
|
||||
};
|
||||
static /*@exposed@*/struct link_name *links;
|
||||
|
||||
static int copy_entry (const char *src, const char *dst,
|
||||
struct path_info {
|
||||
const char *full_path;
|
||||
int dirfd;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int copy_dir (const char *src, const char *dst,
|
||||
static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
#ifdef S_IFLNK
|
||||
static /*@null@*/char *readlink_malloc (const char *filename);
|
||||
static int copy_symlink (const char *src, const char *dst,
|
||||
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
|
||||
unused bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
#endif /* S_IFLNK */
|
||||
static int copy_hardlink (const char *dst,
|
||||
static int copy_hardlink (const struct path_info *dst,
|
||||
unused bool reset_selinux,
|
||||
struct link_name *lp);
|
||||
static int copy_special (const char *src, const char *dst,
|
||||
static int copy_special (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int copy_file (const char *src, const char *dst,
|
||||
static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int chown_if_needed (const char *dst, const struct stat *statp,
|
||||
static int chownat_if_needed (const struct path_info *dst, const struct stat *statp,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int lchown_if_needed (const char *dst, const struct stat *statp,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int fchown_if_needed (int fdst, const struct stat *statp,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
@@ -113,11 +94,13 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
|
||||
/*
|
||||
* error_acl - format the error messages for the ACL and EQ libraries.
|
||||
*/
|
||||
static void error_acl (struct error_context *ctx, const char *fmt, ...)
|
||||
format_attr(printf, 2, 3)
|
||||
static void error_acl (unused struct error_context *ctx, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
/* ignore the case when destination does not support ACLs
|
||||
/* ignore the case when destination does not support ACLs
|
||||
* or extended attributes */
|
||||
if (ENOTSUP == errno) {
|
||||
errno = 0;
|
||||
@@ -125,7 +108,7 @@ static void error_acl (struct error_context *ctx, const char *fmt, ...)
|
||||
}
|
||||
|
||||
va_start (ap, fmt);
|
||||
(void) fprintf (shadow_logfd, _("%s: "), Prog);
|
||||
(void) fprintf (shadow_logfd, _("%s: "), log_get_progname());
|
||||
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
|
||||
(void) fputs (_(": "), shadow_logfd);
|
||||
}
|
||||
@@ -134,10 +117,61 @@ static void error_acl (struct error_context *ctx, const char *fmt, ...)
|
||||
}
|
||||
|
||||
static struct error_context ctx = {
|
||||
error_acl
|
||||
error_acl, NULL, NULL
|
||||
};
|
||||
#endif /* WITH_ACL || WITH_ATTR */
|
||||
|
||||
#ifdef WITH_ACL
|
||||
static int perm_copy_path(const struct path_info *src,
|
||||
const struct path_info *dst,
|
||||
struct error_context *errctx)
|
||||
{
|
||||
int src_fd, dst_fd, ret;
|
||||
|
||||
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (src_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (dst_fd < 0) {
|
||||
(void) close (src_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = perm_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, errctx);
|
||||
(void) close (src_fd);
|
||||
(void) close (dst_fd);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WITH_ACL */
|
||||
|
||||
#ifdef WITH_ATTR
|
||||
static int attr_copy_path(const struct path_info *src,
|
||||
const struct path_info *dst,
|
||||
int (*callback) (const char *, struct error_context *),
|
||||
struct error_context *errctx)
|
||||
{
|
||||
int src_fd, dst_fd, ret;
|
||||
|
||||
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (src_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (dst_fd < 0) {
|
||||
(void) close (src_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = attr_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, callback, errctx);
|
||||
(void) close (src_fd);
|
||||
(void) close (dst_fd);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WITH_ATTR */
|
||||
|
||||
/*
|
||||
* remove_link - delete a link from the linked list
|
||||
*/
|
||||
@@ -194,7 +228,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lp = (struct link_name *) xmalloc (sizeof *lp);
|
||||
lp = XMALLOC(1, struct link_name);
|
||||
src_len = strlen (src_orig);
|
||||
dst_len = strlen (dst_orig);
|
||||
name_len = strlen (name);
|
||||
@@ -202,7 +236,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
lp->ln_ino = sb->st_ino;
|
||||
lp->ln_count = sb->st_nlink;
|
||||
len = name_len - src_len + dst_len + 1;
|
||||
lp->ln_name = (char *) xmalloc (len);
|
||||
lp->ln_name = XMALLOC(len, char);
|
||||
(void) snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len);
|
||||
lp->ln_next = links;
|
||||
links = lp;
|
||||
@@ -210,51 +244,36 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_tree - copy files in a directory tree
|
||||
*
|
||||
* copy_tree() walks a directory tree and copies ordinary files
|
||||
* as it goes.
|
||||
*
|
||||
* When reset_selinux is enabled, extended attributes (and thus
|
||||
* SELinux attributes) are not copied.
|
||||
*
|
||||
* old_uid and new_uid are used to set the ownership of the copied
|
||||
* files. Unless old_uid is set to -1, only the files owned by
|
||||
* old_uid have their ownership changed to new_uid. In addition, if
|
||||
* new_uid is set to -1, no ownership will be changed.
|
||||
*
|
||||
* The same logic applies for the group-ownership and
|
||||
* old_gid/new_gid.
|
||||
*/
|
||||
int copy_tree (const char *src_root, const char *dst_root,
|
||||
static int copy_tree_impl (const struct path_info *src, const struct path_info *dst,
|
||||
bool copy_root, bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
int err = 0;
|
||||
int dst_fd, src_fd, err = 0;
|
||||
bool set_orig = false;
|
||||
struct DIRECT *ent;
|
||||
const struct dirent *ent;
|
||||
DIR *dir;
|
||||
|
||||
if (copy_root) {
|
||||
struct stat sb;
|
||||
if (access (dst_root, F_OK) == 0) {
|
||||
|
||||
if ( fstatat (dst->dirfd, dst->name, &sb, 0) == 0
|
||||
|| errno != ENOENT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LSTAT (src_root, &sb) == -1) {
|
||||
if (fstatat (src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!S_ISDIR (sb.st_mode)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
"%s: %s is not a directory",
|
||||
Prog, src_root);
|
||||
log_get_progname(), src->full_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return copy_entry (src_root, dst_root, reset_selinux,
|
||||
return copy_entry (src, dst, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@@ -264,8 +283,14 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
* target is created. It assumes the target directory exists.
|
||||
*/
|
||||
|
||||
if ( (access (src_root, F_OK) != 0)
|
||||
|| (access (dst_root, F_OK) != 0)) {
|
||||
src_fd = openat (src->dirfd, src->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
||||
if (src_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_fd = openat (dst->dirfd, dst->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
||||
if (dst_fd < 0) {
|
||||
(void) close (src_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -276,14 +301,16 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
* regular files (and directories ...) are copied, and no file
|
||||
* is made set-ID.
|
||||
*/
|
||||
dir = opendir (src_root);
|
||||
dir = fdopendir (src_fd);
|
||||
if (NULL == dir) {
|
||||
(void) close (src_fd);
|
||||
(void) close (dst_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src_orig == NULL) {
|
||||
src_orig = src_root;
|
||||
dst_orig = dst_root;
|
||||
src_orig = src->full_path;
|
||||
dst_orig = dst->full_path;
|
||||
set_orig = true;
|
||||
}
|
||||
while ((0 == err) && (ent = readdir (dir)) != NULL) {
|
||||
@@ -296,11 +323,11 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
char *dst_name;
|
||||
size_t src_len = strlen (ent->d_name) + 2;
|
||||
size_t dst_len = strlen (ent->d_name) + 2;
|
||||
src_len += strlen (src_root);
|
||||
dst_len += strlen (dst_root);
|
||||
src_len += strlen (src->full_path);
|
||||
dst_len += strlen (dst->full_path);
|
||||
|
||||
src_name = (char *) malloc (src_len);
|
||||
dst_name = (char *) malloc (dst_len);
|
||||
src_name = MALLOC(src_len, char);
|
||||
dst_name = MALLOC(dst_len, char);
|
||||
|
||||
if ((NULL == src_name) || (NULL == dst_name)) {
|
||||
err = -1;
|
||||
@@ -309,25 +336,32 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
* Build the filename for both the source and
|
||||
* the destination files.
|
||||
*/
|
||||
(void) snprintf (src_name, src_len, "%s/%s",
|
||||
src_root, ent->d_name);
|
||||
(void) snprintf (dst_name, dst_len, "%s/%s",
|
||||
dst_root, ent->d_name);
|
||||
struct path_info src_entry, dst_entry;
|
||||
|
||||
err = copy_entry (src_name, dst_name,
|
||||
(void) snprintf (src_name, src_len, "%s/%s",
|
||||
src->full_path, ent->d_name);
|
||||
(void) snprintf (dst_name, dst_len, "%s/%s",
|
||||
dst->full_path, ent->d_name);
|
||||
|
||||
src_entry.full_path = src_name;
|
||||
src_entry.dirfd = dirfd(dir);
|
||||
src_entry.name = ent->d_name;
|
||||
|
||||
dst_entry.full_path = dst_name;
|
||||
dst_entry.dirfd = dst_fd;
|
||||
dst_entry.name = ent->d_name;
|
||||
|
||||
err = copy_entry (&src_entry, &dst_entry,
|
||||
reset_selinux,
|
||||
old_uid, new_uid,
|
||||
old_gid, new_gid);
|
||||
}
|
||||
if (NULL != src_name) {
|
||||
free (src_name);
|
||||
}
|
||||
if (NULL != dst_name) {
|
||||
free (dst_name);
|
||||
}
|
||||
free (src_name);
|
||||
free (dst_name);
|
||||
}
|
||||
}
|
||||
(void) closedir (dir);
|
||||
(void) close (dst_fd);
|
||||
|
||||
if (set_orig) {
|
||||
src_orig = NULL;
|
||||
@@ -374,7 +408,7 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
* old_gid) will be modified, unless old_uid (resp. old_gid) is set
|
||||
* to -1.
|
||||
*/
|
||||
static int copy_entry (const char *src, const char *dst,
|
||||
static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@@ -382,41 +416,30 @@ static int copy_entry (const char *src, const char *dst,
|
||||
int err = 0;
|
||||
struct stat sb;
|
||||
struct link_name *lp;
|
||||
struct timeval mt[2];
|
||||
struct timespec mt[2];
|
||||
|
||||
if (LSTAT (src, &sb) == -1) {
|
||||
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
|
||||
/* If we cannot stat the file, do not care. */
|
||||
} else {
|
||||
#ifdef HAVE_STRUCT_STAT_ST_ATIM
|
||||
mt[0].tv_sec = sb.st_atim.tv_sec;
|
||||
mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
|
||||
#else /* !HAVE_STRUCT_STAT_ST_ATIM */
|
||||
mt[0].tv_sec = sb.st_atime;
|
||||
# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
|
||||
mt[0].tv_usec = sb.st_atimensec / 1000;
|
||||
# else /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
mt[0].tv_usec = 0;
|
||||
# endif /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
#endif /* !HAVE_STRUCT_STAT_ST_ATIM */
|
||||
mt[0].tv_nsec = sb.st_atim.tv_nsec;
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||
mt[1].tv_sec = sb.st_mtim.tv_sec;
|
||||
mt[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
|
||||
#else /* !HAVE_STRUCT_STAT_ST_MTIM */
|
||||
mt[1].tv_sec = sb.st_mtime;
|
||||
# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
mt[1].tv_usec = sb.st_mtimensec / 1000;
|
||||
# else /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
|
||||
mt[1].tv_usec = 0;
|
||||
# endif /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
|
||||
#endif /* !HAVE_STRUCT_STAT_ST_MTIM */
|
||||
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
|
||||
|
||||
if (S_ISDIR (sb.st_mode)) {
|
||||
err = copy_dir (src, dst, reset_selinux, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
#ifdef S_IFLNK
|
||||
/*
|
||||
* If the destination already exists do nothing.
|
||||
* This is after the copy_dir above to still iterate into subdirectories.
|
||||
*/
|
||||
if (fstatat(dst->dirfd, dst->name, &sb, AT_SYMLINK_NOFOLLOW) != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy any symbolic links
|
||||
*/
|
||||
@@ -425,13 +448,12 @@ static int copy_entry (const char *src, const char *dst,
|
||||
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
#endif /* S_IFLNK */
|
||||
|
||||
/*
|
||||
* See if this is a previously copied link
|
||||
*/
|
||||
|
||||
else if ((lp = check_link (src, &sb)) != NULL) {
|
||||
else if ((lp = check_link (src->full_path, &sb)) != NULL) {
|
||||
err = copy_hardlink (dst, reset_selinux, lp);
|
||||
}
|
||||
|
||||
@@ -470,13 +492,14 @@ static int copy_entry (const char *src, const char *dst,
|
||||
*
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_dir (const char *src, const char *dst,
|
||||
static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
int err = 0;
|
||||
struct stat dst_sb;
|
||||
|
||||
/*
|
||||
* Create a new target directory, make it owned by
|
||||
@@ -484,19 +507,27 @@ static int copy_dir (const char *src, const char *dst,
|
||||
*/
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (dst, S_IFDIR) != 0) {
|
||||
if (set_selinux_file_context (dst->full_path, S_IFDIR) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
if ( (mkdir (dst, statp->st_mode) != 0)
|
||||
|| (chown_if_needed (dst, statp,
|
||||
/*
|
||||
* If the destination is already a directory, don't change it
|
||||
* but copy into it (recursively).
|
||||
*/
|
||||
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
|
||||
return (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0);
|
||||
}
|
||||
|
||||
if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|
||||
|| (chownat_if_needed (dst, statp,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||
|| (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
#ifdef WITH_ACL
|
||||
|| ( (perm_copy_file (src, dst, &ctx) != 0)
|
||||
|| ( (perm_copy_path (src, dst, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#else /* !WITH_ACL */
|
||||
|| (chmod (dst, statp->st_mode) != 0)
|
||||
#endif /* !WITH_ACL */
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
@@ -506,19 +537,18 @@ static int copy_dir (const char *src, const char *dst,
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
|| ( !reset_selinux
|
||||
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
|
||||
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ATTR */
|
||||
|| (copy_tree (src, dst, false, reset_selinux,
|
||||
|| (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||
|| (utimes (dst, mt) != 0)) {
|
||||
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
|
||||
err = -1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef S_IFLNK
|
||||
/*
|
||||
* readlink_malloc - wrapper for readlink
|
||||
*
|
||||
@@ -531,7 +561,7 @@ static /*@null@*/char *readlink_malloc (const char *filename)
|
||||
|
||||
while (true) {
|
||||
ssize_t nchars;
|
||||
char *buffer = (char *) malloc (size);
|
||||
char *buffer = MALLOC(size, char);
|
||||
if (NULL == buffer) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -565,9 +595,9 @@ static /*@null@*/char *readlink_malloc (const char *filename)
|
||||
*
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_symlink (const char *src, const char *dst,
|
||||
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
|
||||
unused bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
@@ -585,7 +615,7 @@ static int copy_symlink (const char *src, const char *dst,
|
||||
* destination directory name.
|
||||
*/
|
||||
|
||||
oldlink = readlink_malloc (src);
|
||||
oldlink = readlink_malloc (src->full_path);
|
||||
if (NULL == oldlink) {
|
||||
return -1;
|
||||
}
|
||||
@@ -596,7 +626,7 @@ static int copy_symlink (const char *src, const char *dst,
|
||||
*/
|
||||
if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
|
||||
size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
|
||||
char *dummy = (char *) xmalloc (len);
|
||||
char *dummy = XMALLOC(len, char);
|
||||
(void) snprintf (dummy, len, "%s%s",
|
||||
dst_orig,
|
||||
oldlink + strlen (src_orig));
|
||||
@@ -605,13 +635,13 @@ static int copy_symlink (const char *src, const char *dst,
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (dst, S_IFLNK) != 0) {
|
||||
if (set_selinux_file_context (dst->full_path, S_IFLNK) != 0) {
|
||||
free (oldlink);
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
if ( (symlink (oldlink, dst) != 0)
|
||||
|| (lchown_if_needed (dst, statp,
|
||||
if ( (symlinkat (oldlink, dst->dirfd, dst->name) != 0)
|
||||
|| (chownat_if_needed (dst, statp,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)) {
|
||||
/* FIXME: there are no modes on symlinks, right?
|
||||
* ACL could be copied, but this would be much more
|
||||
@@ -625,18 +655,12 @@ static int copy_symlink (const char *src, const char *dst,
|
||||
}
|
||||
free (oldlink);
|
||||
|
||||
#ifdef HAVE_LUTIMES
|
||||
/* 2007-10-18: We don't care about
|
||||
* exit status of lutimes because
|
||||
* it returns ENOSYS on many system
|
||||
* - not implemented
|
||||
*/
|
||||
(void) lutimes (dst, mt);
|
||||
#endif /* HAVE_LUTIMES */
|
||||
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* S_IFLNK */
|
||||
|
||||
/*
|
||||
* copy_hardlink - copy a hardlink
|
||||
@@ -645,13 +669,13 @@ static int copy_symlink (const char *src, const char *dst,
|
||||
*
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_hardlink (const char *dst,
|
||||
static int copy_hardlink (const struct path_info *dst,
|
||||
unused bool reset_selinux,
|
||||
struct link_name *lp)
|
||||
{
|
||||
/* FIXME: selinux, ACL, Extended Attributes needed? */
|
||||
|
||||
if (link (lp->ln_name, dst) != 0) {
|
||||
if (linkat (AT_FDCWD, lp->ln_name, dst->dirfd, dst->name, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -675,29 +699,28 @@ static int copy_hardlink (const char *dst,
|
||||
*
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_special (const char *src, const char *dst,
|
||||
static int copy_special (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (dst, statp->st_mode & S_IFMT) != 0) {
|
||||
if (set_selinux_file_context (dst->full_path, statp->st_mode & S_IFMT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
if ( (mknod (dst, statp->st_mode & ~07777, statp->st_rdev) != 0)
|
||||
|| (chown_if_needed (dst, statp,
|
||||
if ( (mknodat (dst->dirfd, dst->name, statp->st_mode & ~07777U, statp->st_rdev) != 0)
|
||||
|| (chownat_if_needed (dst, statp,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||
|| (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
#ifdef WITH_ACL
|
||||
|| ( (perm_copy_file (src, dst, &ctx) != 0)
|
||||
|| ( (perm_copy_path (src, dst, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#else /* !WITH_ACL */
|
||||
|| (chmod (dst, statp->st_mode & 07777) != 0)
|
||||
#endif /* !WITH_ACL */
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
@@ -707,10 +730,10 @@ static int copy_special (const char *src, const char *dst,
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
|| ( !reset_selinux
|
||||
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
|
||||
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ATTR */
|
||||
|| (utimes (dst, mt) != 0)) {
|
||||
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
|
||||
err = -1;
|
||||
}
|
||||
|
||||
@@ -727,38 +750,35 @@ static int copy_special (const char *src, const char *dst,
|
||||
*
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_file (const char *src, const char *dst,
|
||||
static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timeval mt[],
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
int err = 0;
|
||||
int ifd;
|
||||
int ofd;
|
||||
char buf[1024];
|
||||
ssize_t cnt;
|
||||
|
||||
ifd = open (src, O_RDONLY);
|
||||
ifd = openat (src->dirfd, src->name, O_RDONLY|O_NOFOLLOW|O_CLOEXEC);
|
||||
if (ifd < 0) {
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (dst, S_IFREG) != 0) {
|
||||
if (set_selinux_file_context (dst->full_path, S_IFREG) != 0) {
|
||||
(void) close (ifd);
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
ofd = open (dst, O_WRONLY | O_CREAT | O_TRUNC, statp->st_mode & 07777);
|
||||
ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, 0600);
|
||||
if ( (ofd < 0)
|
||||
|| (fchown_if_needed (ofd, statp,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||
#ifdef WITH_ACL
|
||||
|| ( (perm_copy_fd (src, ifd, dst, ofd, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#else /* !WITH_ACL */
|
||||
|| (fchmod (ofd, statp->st_mode & 07777) != 0)
|
||||
#endif /* !WITH_ACL */
|
||||
#ifdef WITH_ACL
|
||||
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
@@ -768,7 +788,7 @@ static int copy_file (const char *src, const char *dst,
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
|| ( !reset_selinux
|
||||
&& (attr_copy_fd (src, ifd, dst, ofd, NULL, &ctx) != 0)
|
||||
&& (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ATTR */
|
||||
) {
|
||||
@@ -779,8 +799,24 @@ static int copy_file (const char *src, const char *dst,
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
|
||||
if (write (ofd, buf, (size_t)cnt) != cnt) {
|
||||
while (true) {
|
||||
char buf[8192];
|
||||
ssize_t cnt;
|
||||
|
||||
cnt = read (ifd, buf, sizeof buf);
|
||||
if (cnt < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
(void) close (ofd);
|
||||
(void) close (ifd);
|
||||
return -1;
|
||||
}
|
||||
if (cnt == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (write_full (ofd, buf, cnt) < 0) {
|
||||
(void) close (ofd);
|
||||
(void) close (ifd);
|
||||
return -1;
|
||||
@@ -788,23 +824,13 @@ static int copy_file (const char *src, const char *dst,
|
||||
}
|
||||
|
||||
(void) close (ifd);
|
||||
|
||||
#ifdef HAVE_FUTIMES
|
||||
if (futimes (ofd, mt) != 0) {
|
||||
(void) close (ofd);
|
||||
return -1;
|
||||
}
|
||||
#endif /* HAVE_FUTIMES */
|
||||
|
||||
if (close (ofd) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef HAVE_FUTIMES
|
||||
if (utimes(dst, mt) != 0) {
|
||||
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif /* !HAVE_FUTIMES */
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -839,7 +865,70 @@ static int chown_function ## _if_needed (type_dst dst, \
|
||||
return chown_function (dst, tmpuid, tmpgid); \
|
||||
}
|
||||
|
||||
def_chown_if_needed (chown, const char *)
|
||||
def_chown_if_needed (lchown, const char *)
|
||||
def_chown_if_needed (fchown, int)
|
||||
|
||||
static int chownat_if_needed (const struct path_info *dst,
|
||||
const struct stat *statp,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
uid_t tmpuid = (uid_t) -1;
|
||||
gid_t tmpgid = (gid_t) -1;
|
||||
|
||||
/* Use new_uid if old_uid is set to -1 or if the file was
|
||||
* owned by the user. */
|
||||
if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) {
|
||||
tmpuid = new_uid;
|
||||
}
|
||||
/* Otherwise, or if new_uid was set to -1, we keep the same
|
||||
* owner. */
|
||||
if ((uid_t) -1 == tmpuid) {
|
||||
tmpuid = statp->st_uid;
|
||||
}
|
||||
|
||||
if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) {
|
||||
tmpgid = new_gid;
|
||||
}
|
||||
if ((gid_t) -1 == tmpgid) {
|
||||
tmpgid = statp->st_gid;
|
||||
}
|
||||
|
||||
return fchownat (dst->dirfd, dst->name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_tree - copy files in a directory tree
|
||||
*
|
||||
* copy_tree() walks a directory tree and copies ordinary files
|
||||
* as it goes.
|
||||
*
|
||||
* When reset_selinux is enabled, extended attributes (and thus
|
||||
* SELinux attributes) are not copied.
|
||||
*
|
||||
* old_uid and new_uid are used to set the ownership of the copied
|
||||
* files. Unless old_uid is set to -1, only the files owned by
|
||||
* old_uid have their ownership changed to new_uid. In addition, if
|
||||
* new_uid is set to -1, no ownership will be changed.
|
||||
*
|
||||
* The same logic applies for the group-ownership and
|
||||
* old_gid/new_gid.
|
||||
*/
|
||||
int copy_tree (const char *src_root, const char *dst_root,
|
||||
bool copy_root, bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
const struct path_info src = {
|
||||
.full_path = src_root,
|
||||
.dirfd = AT_FDCWD,
|
||||
.name = src_root
|
||||
};
|
||||
const struct path_info dst = {
|
||||
.full_path = dst_root,
|
||||
.dirfd = AT_FDCWD,
|
||||
.name = dst_root
|
||||
};
|
||||
|
||||
return copy_tree_impl(&src, &dst, copy_root, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
141
lib/csrand.c
Normal file
141
lib/csrand.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#if HAVE_SYS_RANDOM_H
|
||||
#include <sys/random.h>
|
||||
#endif
|
||||
#include "bit.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
static uint32_t csrand_uniform32(uint32_t n);
|
||||
static unsigned long csrand_uniform_slow(unsigned long n);
|
||||
|
||||
|
||||
/*
|
||||
* Return a uniformly-distributed CS random u_long value.
|
||||
*/
|
||||
unsigned long
|
||||
csrand(void)
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned long r;
|
||||
|
||||
#ifdef HAVE_GETENTROPY
|
||||
/* getentropy may exist but lack kernel support. */
|
||||
if (getentropy(&r, sizeof(r)) == 0)
|
||||
return r;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRANDOM
|
||||
/* Likewise getrandom. */
|
||||
if (getrandom(&r, sizeof(r), 0) == sizeof(r))
|
||||
return r;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARC4RANDOM_BUF
|
||||
/* arc4random_buf can never fail. */
|
||||
arc4random_buf(&r, sizeof(r));
|
||||
return r;
|
||||
#endif
|
||||
|
||||
/* Use /dev/urandom as a last resort. */
|
||||
fp = fopen("/dev/urandom", "r");
|
||||
if (NULL == fp) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fread(&r, sizeof(r), 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return r;
|
||||
|
||||
fail:
|
||||
fprintf(log_get_logfd(), _("Unable to obtain random bytes.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a uniformly-distributed CS random value in the interval [0, n-1].
|
||||
*/
|
||||
unsigned long
|
||||
csrand_uniform(unsigned long n)
|
||||
{
|
||||
if (n == 0 || n > UINT32_MAX)
|
||||
return csrand_uniform_slow(n);
|
||||
|
||||
return csrand_uniform32(n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a uniformly-distributed CS random value in the interval [min, max].
|
||||
*/
|
||||
unsigned long
|
||||
csrand_interval(unsigned long min, unsigned long max)
|
||||
{
|
||||
return csrand_uniform(max - min + 1) + min;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast Random Integer Generation in an Interval
|
||||
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
|
||||
* <https://arxiv.org/abs/1805.10941>
|
||||
*/
|
||||
static uint32_t
|
||||
csrand_uniform32(uint32_t n)
|
||||
{
|
||||
uint32_t bound, rem;
|
||||
uint64_t r, mult;
|
||||
|
||||
if (n == 0)
|
||||
return csrand();
|
||||
|
||||
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
|
||||
|
||||
do {
|
||||
r = csrand();
|
||||
mult = r * n;
|
||||
rem = mult; // analogous to `mult % 2^32`
|
||||
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
|
||||
|
||||
r = mult >> WIDTHOF(n); // analogous to `mult / 2^32`
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
csrand_uniform_slow(unsigned long n)
|
||||
{
|
||||
unsigned long r, max, mask;
|
||||
|
||||
max = n - 1;
|
||||
mask = bit_ceil_wrapul(n) - 1;
|
||||
|
||||
do {
|
||||
r = csrand();
|
||||
r &= mask; // optimization
|
||||
} while (r > max); // p = ((mask+1) % n) / (mask+1); W.C.: p=0.5
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
|
||||
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2021, Alejandro Colomar <alx.manpages@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -29,22 +26,31 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* basename.c - not worth copyrighting :-). Some versions of Linux libc
|
||||
* already have basename(), other versions don't. To avoid confusion,
|
||||
* we will not use the function from libc and use a different name here.
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*@observer@*/const char *Basename (const char *str)
|
||||
{
|
||||
char *cp = strrchr (str, '/');
|
||||
|
||||
return (NULL != cp) ? cp + 1 : str;
|
||||
void
|
||||
date_to_str(size_t size, char buf[size], long date)
|
||||
{
|
||||
time_t t;
|
||||
const struct tm *tm;
|
||||
|
||||
t = date;
|
||||
if (date < 0) {
|
||||
(void) strlcpy(buf, "never", size);
|
||||
return;
|
||||
}
|
||||
|
||||
tm = gmtime(&t);
|
||||
if (tm == NULL) {
|
||||
(void) strlcpy(buf, "future", size);
|
||||
return;
|
||||
}
|
||||
|
||||
(void) strftime(buf, size, "%Y-%m-%d", tm);
|
||||
buf[size - 1] = '\0';
|
||||
}
|
||||
231
lib/defines.h
231
lib/defines.h
@@ -6,43 +6,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# if ! HAVE__BOOL
|
||||
# ifdef __cplusplus
|
||||
typedef bool _Bool;
|
||||
# else
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
# endif
|
||||
# define bool _Bool
|
||||
# define false (0)
|
||||
# define true (1)
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
|
||||
/* Take care of NLS matters. */
|
||||
#ifdef S_SPLINT_S
|
||||
extern char *setlocale(int categories, const char *locale);
|
||||
# define LC_ALL (6)
|
||||
extern char * bindtextdomain (const char * domainname, const char * dirname);
|
||||
extern char * textdomain (const char * domainname);
|
||||
# define _(Text) Text
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
#else
|
||||
#ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#else
|
||||
# undef setlocale
|
||||
# define setlocale(category, locale) (NULL)
|
||||
# ifndef LC_ALL
|
||||
# define LC_ALL 6
|
||||
# endif
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <locale.h>
|
||||
|
||||
#define gettext_noop(String) (String)
|
||||
/* #define gettext_def(String) "#define String" */
|
||||
@@ -59,42 +24,17 @@ extern char * textdomain (const char * domainname);
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else /* not STDC_HEADERS */
|
||||
# ifndef HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr (), *strrchr (), *strtok ();
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy((s), (d), (n))
|
||||
# endif
|
||||
#endif /* not STDC_HEADERS */
|
||||
|
||||
#if HAVE_ERRNO_H
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* crypt(3), crypt_gensalt(3), and their
|
||||
@@ -104,39 +44,24 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else /* not TIME_WITH_SYS_TIME */
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif /* not TIME_WITH_SYS_TIME */
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_MEMSET_EXPLICIT
|
||||
# define memzero(ptr, size) memset_explicit((ptr), 0, (size))
|
||||
#elif defined HAVE_EXPLICIT_BZERO /* !HAVE_MEMSET_S */
|
||||
# define memzero(ptr, size) explicit_bzero((ptr), (size))
|
||||
#else /* !HAVE_MEMSET_S && HAVE_EXPLICIT_BZERO */
|
||||
static inline void memzero(void *ptr, size_t size)
|
||||
{
|
||||
ptr = memset(ptr, '\0', size);
|
||||
__asm__ __volatile__ ("" : : "r"(ptr) : "memory");
|
||||
}
|
||||
#endif /* !HAVE_MEMSET_S && !HAVE_EXPLICIT_BZERO */
|
||||
|
||||
#ifdef HAVE_MEMSET
|
||||
# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
|
||||
#else
|
||||
# define memzero(ptr, size) bzero((char *)(ptr), (size))
|
||||
#endif
|
||||
#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
|
||||
|
||||
#ifdef HAVE_DIRENT_H /* DIR_SYSV */
|
||||
# include <dirent.h>
|
||||
# define DIRECT dirent
|
||||
#else
|
||||
# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# ifdef HAVE_SYS_DIR_H /* DIR_??? */
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# ifdef HAVE_NDIR_H /* DIR_BSD */
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# define DIRECT direct
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* Possible cases:
|
||||
@@ -158,7 +83,6 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
#include <syslog.h>
|
||||
|
||||
#ifndef LOG_WARN
|
||||
@@ -205,14 +129,6 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
#define SYSLOG(x) syslog x
|
||||
#endif /* !ENABLE_NLS */
|
||||
|
||||
#else /* !USE_SYSLOG */
|
||||
|
||||
#define SYSLOG(x) /* empty */
|
||||
#define openlog(a,b,c) /* empty */
|
||||
#define closelog() /* empty */
|
||||
|
||||
#endif /* !USE_SYSLOG */
|
||||
|
||||
/* The default syslog settings can now be changed here,
|
||||
in just one place. */
|
||||
|
||||
@@ -227,57 +143,10 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
|
||||
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
# define X_OK 1
|
||||
# define W_OK 2
|
||||
# define R_OK 4
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
# define SEEK_CUR 1
|
||||
# define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR)
|
||||
# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG)
|
||||
# ifdef S_IFLNK
|
||||
# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(x) (0)
|
||||
#endif
|
||||
|
||||
#if HAVE_LCHOWN
|
||||
#define LCHOWN lchown
|
||||
#else
|
||||
#define LCHOWN chown
|
||||
#endif
|
||||
|
||||
#if HAVE_LSTAT
|
||||
#define LSTAT lstat
|
||||
#else
|
||||
#define LSTAT stat
|
||||
#endif
|
||||
|
||||
#if HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
||||
# define GTTY(fd, termio) tcgetattr(fd, termio)
|
||||
# define TERMIO struct termios
|
||||
# define USE_TERMIOS
|
||||
#else /* assumed HAVE_TERMIO_H */
|
||||
# include <sys/ioctl.h>
|
||||
# include <termio.h>
|
||||
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
|
||||
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
|
||||
# define TEMRIO struct termio
|
||||
# define USE_TERMIO
|
||||
#endif
|
||||
#include <termios.h>
|
||||
#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
||||
#define GTTY(fd, termio) tcgetattr(fd, termio)
|
||||
#define TERMIO struct termios
|
||||
|
||||
/*
|
||||
* Password aging constants
|
||||
@@ -300,6 +169,10 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
#define SCALE DAY
|
||||
#endif
|
||||
|
||||
#define WIDTHOF(x) (sizeof(x) * CHAR_BIT)
|
||||
#define NITEMS(arr) (sizeof((arr)) / sizeof((arr)[0]))
|
||||
#define STRLEN(s) (NITEMS(s) - 1)
|
||||
|
||||
/* Copy string pointed by B to array A with size checking. It was originally
|
||||
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
|
||||
very sloppy coding used to assume that BUFSIZ will always be enough... */
|
||||
@@ -326,18 +199,6 @@ char *strchr (), *strrchr (), *strtok ();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#ifdef sun /* hacks for compiling on SunOS */
|
||||
# ifndef SOLARIS
|
||||
extern int fputs ();
|
||||
extern char *strdup ();
|
||||
extern char *strerror ();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* string to use for the pw_passwd field in /etc/passwd when using
|
||||
* shadow passwords - most systems use "x" but there are a few
|
||||
@@ -362,34 +223,22 @@ extern char *strerror ();
|
||||
|
||||
/* To be used for verified unused parameters */
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
# define unused __attribute__((unused))
|
||||
# define unused __attribute__((unused))
|
||||
# define NORETURN __attribute__((__noreturn__))
|
||||
# define format_attr(type, index, check) __attribute__((format (type, index, check)))
|
||||
#else
|
||||
# define unused
|
||||
# define NORETURN
|
||||
# define format_attr(type, index, check)
|
||||
#endif
|
||||
|
||||
/* ! Arguments evaluated twice ! */
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
/* Maximum length of passwd entry */
|
||||
#define PASSWD_ENTRY_MAX_LENGTH 32768
|
||||
|
||||
/* Maximum length of usernames */
|
||||
#ifdef HAVE_UTMPX_H
|
||||
# include <utmpx.h>
|
||||
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
|
||||
#if (__GNUC__ >= 11) && !defined(__clang__)
|
||||
# define ATTR_MALLOC(deallocator) [[gnu::malloc(deallocator)]]
|
||||
#else
|
||||
# include <utmp.h>
|
||||
# ifdef HAVE_STRUCT_UTMP_UT_USER
|
||||
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
|
||||
# else
|
||||
# ifdef HAVE_STRUCT_UTMP_UT_NAME
|
||||
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
|
||||
# else
|
||||
# define USER_NAME_MAX_LENGTH 32
|
||||
# endif
|
||||
# endif
|
||||
# define ATTR_MALLOC(deallocator)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SECURE_GETENV
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1990 - 1993, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
||||
* Copyright (c) 2005 , Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2010, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1990 - 1993, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -39,6 +16,7 @@
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "shadowlog_internal.h"
|
||||
|
||||
/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
|
||||
{
|
||||
|
||||
47
lib/entry.c
Normal file
47
lib/entry.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
void pw_entry (const char *name, struct passwd *pwent)
|
||||
{
|
||||
struct passwd *passwd;
|
||||
|
||||
struct spwd *spwd;
|
||||
|
||||
if (!(passwd = getpwnam (name))) { /* local, no need for xgetpwnam */
|
||||
pwent->pw_name = NULL;
|
||||
return;
|
||||
} else {
|
||||
pwent->pw_name = xstrdup (passwd->pw_name);
|
||||
pwent->pw_uid = passwd->pw_uid;
|
||||
pwent->pw_gid = passwd->pw_gid;
|
||||
pwent->pw_gecos = xstrdup (passwd->pw_gecos);
|
||||
pwent->pw_dir = xstrdup (passwd->pw_dir);
|
||||
pwent->pw_shell = xstrdup (passwd->pw_shell);
|
||||
#if !defined(AUTOSHADOW)
|
||||
/* local, no need for xgetspnam */
|
||||
if ((spwd = getspnam (name))) {
|
||||
pwent->pw_passwd = xstrdup (spwd->sp_pwdp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
pwent->pw_passwd = xstrdup (passwd->pw_passwd);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1989 - 1992, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
|
||||
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
|
||||
* Copyright (c) 2008 - 2009, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1989 - 1992, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -38,8 +15,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "shadowlog.h"
|
||||
/*
|
||||
* NEWENVP_STEP must be a power of two. This is the number
|
||||
* of (char *) pointers to allocate at a time, to avoid using
|
||||
@@ -48,9 +28,8 @@
|
||||
#define NEWENVP_STEP 16
|
||||
size_t newenvc = 0;
|
||||
/*@null@*/char **newenvp = NULL;
|
||||
extern char **environ;
|
||||
|
||||
static const char *forbid[] = {
|
||||
static const char *const forbid[] = {
|
||||
"_RLD_=",
|
||||
"BASH_ENV=", /* GNU creeping featurism strikes again... */
|
||||
"ENV=",
|
||||
@@ -64,16 +43,16 @@ static const char *forbid[] = {
|
||||
"PATH=",
|
||||
"SHELL=",
|
||||
"SHLIB_PATH=",
|
||||
(char *) 0
|
||||
NULL
|
||||
};
|
||||
|
||||
/* these are allowed, but with no slashes inside
|
||||
(to work around security problems in GNU gettext) */
|
||||
static const char *noslash[] = {
|
||||
static const char *const noslash[] = {
|
||||
"LANG=",
|
||||
"LANGUAGE=",
|
||||
"LC_", /* anything with the LC_ prefix */
|
||||
(char *) 0
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -81,7 +60,7 @@ static const char *noslash[] = {
|
||||
*/
|
||||
void initenv (void)
|
||||
{
|
||||
newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *));
|
||||
newenvp = XMALLOC(NEWENVP_STEP, char *);
|
||||
*newenvp = NULL;
|
||||
}
|
||||
|
||||
@@ -95,7 +74,7 @@ void addenv (const char *string, /*@null@*/const char *value)
|
||||
if (NULL != value) {
|
||||
size_t len = strlen (string) + strlen (value) + 2;
|
||||
int wlen;
|
||||
newstring = xmalloc (len);
|
||||
newstring = XMALLOC(len, char);
|
||||
wlen = snprintf (newstring, len, "%s=%s", string, value);
|
||||
assert (wlen == (int) len -1);
|
||||
} else {
|
||||
@@ -149,16 +128,16 @@ void addenv (const char *string, /*@null@*/const char *value)
|
||||
*/
|
||||
|
||||
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
|
||||
char **__newenvp;
|
||||
size_t newsize;
|
||||
bool update_environ;
|
||||
char **__newenvp;
|
||||
|
||||
/*
|
||||
* If the resize operation succeeds we can
|
||||
* happily go on, else print a message.
|
||||
*/
|
||||
update_environ = (environ == newenvp);
|
||||
|
||||
newsize = (newenvc + NEWENVP_STEP) * sizeof (char *);
|
||||
__newenvp = (char **) realloc (newenvp, newsize);
|
||||
__newenvp = REALLOC(newenvp, newenvc + NEWENVP_STEP, char *);
|
||||
|
||||
if (NULL != __newenvp) {
|
||||
/*
|
||||
@@ -166,12 +145,11 @@ void addenv (const char *string, /*@null@*/const char *value)
|
||||
* environ so that it doesn't point to some
|
||||
* free memory area (realloc() could move it).
|
||||
*/
|
||||
if (environ == newenvp) {
|
||||
if (update_environ)
|
||||
environ = __newenvp;
|
||||
}
|
||||
newenvp = __newenvp;
|
||||
} else {
|
||||
(void) fputs (_("Environment overflow\n"), shadow_logfd);
|
||||
(void) fputs (_("Environment overflow\n"), log_get_logfd());
|
||||
newenvc--;
|
||||
free (newenvp[newenvc]);
|
||||
}
|
||||
@@ -207,7 +185,7 @@ void set_env (int argc, char *const *argv)
|
||||
noname++;
|
||||
addenv (variable, *argv);
|
||||
} else {
|
||||
const char **p;
|
||||
const char *const *p;
|
||||
|
||||
for (p = forbid; NULL != *p; p++) {
|
||||
if (strncmp (*argv, *p, strlen (*p)) == 0) {
|
||||
@@ -240,7 +218,7 @@ void set_env (int argc, char *const *argv)
|
||||
void sanitize_env (void)
|
||||
{
|
||||
char **envp = environ;
|
||||
const char **bad;
|
||||
const char *const *bad;
|
||||
char **cur;
|
||||
char **move;
|
||||
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005 - 2006, Tomasz Kłoczko
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2005 - 2006, Tomasz Kłoczko
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
|
||||
* Copyright (c) 2005 , Tomasz Kłoczko
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -45,8 +22,8 @@
|
||||
struct faillog {
|
||||
short fail_cnt; /* failures since last success */
|
||||
short fail_max; /* failures before turning account off */
|
||||
char fail_line[12]; /* last failure occured here */
|
||||
time_t fail_time; /* last failure occured then */
|
||||
char fail_line[12]; /* last failure occurred here */
|
||||
time_t fail_time; /* last failure occurred then */
|
||||
/*
|
||||
* If nonzero, the account will be re-enabled if there are no
|
||||
* failures for fail_locktime seconds since last failure.
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
|
||||
* Copyright (c) 2002 - 2005, Tomasz Kłoczko
|
||||
* Copyright (c) 2008 - 2010, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2002 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 - 2010, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -39,8 +16,8 @@
|
||||
#include <unistd.h>
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include "getdef.h"
|
||||
#include "failure.h"
|
||||
#include "prototypes.h"
|
||||
#define YEAR (365L*DAY)
|
||||
/*
|
||||
* failure - make failure entry
|
||||
@@ -76,7 +53,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
/* This is not necessarily a failure. The file is
|
||||
* initially zero length.
|
||||
*
|
||||
@@ -109,7 +86,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
|
||||
|| (write_full (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)
|
||||
|| (close (fd) != 0)) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't write faillog entry for UID %lu in %s.",
|
||||
@@ -186,7 +163,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
(void) close (fd);
|
||||
return 1;
|
||||
}
|
||||
@@ -208,7 +185,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
fail.fail_cnt = 0;
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|
||||
|| (write_full (fd, &fail, sizeof fail) != (ssize_t) sizeof fail)
|
||||
|| (close (fd) != 0)) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't reset faillog entry for UID %lu in %s.",
|
||||
@@ -232,13 +209,8 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
void failprint (const struct faillog *fail)
|
||||
{
|
||||
struct tm *tp;
|
||||
|
||||
#if HAVE_STRFTIME
|
||||
char lasttimeb[256];
|
||||
char *lasttime = lasttimeb;
|
||||
#else
|
||||
char *lasttime;
|
||||
#endif
|
||||
time_t NOW;
|
||||
|
||||
if (0 == fail->fail_cnt) {
|
||||
@@ -248,31 +220,11 @@ void failprint (const struct faillog *fail)
|
||||
tp = localtime (&(fail->fail_time));
|
||||
(void) time (&NOW);
|
||||
|
||||
#if HAVE_STRFTIME
|
||||
/*
|
||||
* Print all information we have.
|
||||
*/
|
||||
(void) strftime (lasttimeb, sizeof lasttimeb, "%c", tp);
|
||||
#else
|
||||
|
||||
/*
|
||||
* Do the same thing, but don't use strftime since it
|
||||
* probably doesn't exist on this system
|
||||
*/
|
||||
lasttime = asctime (tp);
|
||||
lasttime[24] = '\0';
|
||||
|
||||
if ((NOW - fail->fail_time) < YEAR) {
|
||||
lasttime[19] = '\0';
|
||||
}
|
||||
if ((NOW - fail->fail_time) < DAY) {
|
||||
lasttime = lasttime + 11;
|
||||
}
|
||||
|
||||
if (' ' == *lasttime) {
|
||||
lasttime++;
|
||||
}
|
||||
#endif
|
||||
/*@-formatconst@*/
|
||||
(void) printf (ngettext ("%d failure since last login.\n"
|
||||
"Last was %s on %s.\n",
|
||||
@@ -282,62 +234,3 @@ void failprint (const struct faillog *fail)
|
||||
fail->fail_cnt, lasttime, fail->fail_line);
|
||||
/*@=formatconst@*/
|
||||
}
|
||||
|
||||
/*
|
||||
* failtmp - update the cumulative failure log
|
||||
*
|
||||
* failtmp updates the (struct utmp) formatted failure log which
|
||||
* maintains a record of all login failures.
|
||||
*/
|
||||
|
||||
void failtmp (const char *username,
|
||||
#ifdef USE_UTMPX
|
||||
const struct utmpx *failent
|
||||
#else /* !USE_UTMPX */
|
||||
const struct utmp *failent
|
||||
#endif /* !USE_UTMPX */
|
||||
)
|
||||
{
|
||||
const char *ftmp;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Get the name of the failure file. If no file has been defined
|
||||
* in login.defs, don't do this.
|
||||
*/
|
||||
|
||||
ftmp = getdef_str ("FTMP_FILE");
|
||||
if (NULL == ftmp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file for append. It must already exist for this
|
||||
* feature to be used.
|
||||
*/
|
||||
|
||||
if (access (ftmp, F_OK) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open (ftmp, O_WRONLY | O_APPEND);
|
||||
if (-1 == fd) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't append failure of user %s to %s.",
|
||||
username, ftmp));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the new failure record and close the log file.
|
||||
*/
|
||||
|
||||
if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
|
||||
|| (close (fd) != 0)) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't append failure of user %s to %s.",
|
||||
username, ftmp));
|
||||
(void) close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
44
lib/failure.h
Normal file
44
lib/failure.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
#ifndef _FAILURE_H_
|
||||
#define _FAILURE_H_
|
||||
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
|
||||
/*
|
||||
* failure - make failure entry
|
||||
*
|
||||
* failure() creates a new (struct faillog) entry or updates an
|
||||
* existing one with the current failed login information.
|
||||
*/
|
||||
extern void failure (uid_t, const char *, struct faillog *);
|
||||
|
||||
/*
|
||||
* failcheck - check for failures > allowable
|
||||
*
|
||||
* failcheck() is called AFTER the password has been validated. If the
|
||||
* account has been "attacked" with too many login failures, failcheck()
|
||||
* returns FALSE to indicate that the login should be denied even though
|
||||
* the password is valid.
|
||||
*/
|
||||
extern int failcheck (uid_t uid, struct faillog *fl, bool failed);
|
||||
|
||||
/*
|
||||
* failprint - print line of failure information
|
||||
*
|
||||
* failprint takes a (struct faillog) entry and formats it into a
|
||||
* message which is displayed at login time.
|
||||
*/
|
||||
extern void failprint (const struct faillog *);
|
||||
|
||||
#endif
|
||||
|
||||
75
lib/fields.c
75
lib/fields.c
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1990 , Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
|
||||
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1990 , Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -44,9 +21,9 @@
|
||||
*
|
||||
* The supplied field is scanned for non-printable and other illegal
|
||||
* characters.
|
||||
* + -1 is returned if an illegal character is present.
|
||||
* + 1 is returned if no illegal characters are present, but the field
|
||||
* contains a non-printable character.
|
||||
* + -1 is returned if an illegal or control character is present.
|
||||
* + 1 is returned if no illegal or control characters are present,
|
||||
* but the field contains a non-printable character.
|
||||
* + 0 is returned otherwise.
|
||||
*/
|
||||
int valid_field (const char *field, const char *illegal)
|
||||
@@ -60,20 +37,19 @@ int valid_field (const char *field, const char *illegal)
|
||||
|
||||
/* For each character of field, search if it appears in the list
|
||||
* of illegal characters. */
|
||||
for (cp = field; '\0' != *cp; cp++) {
|
||||
if (strchr (illegal, *cp) != NULL) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
if (illegal && NULL != strpbrk (field, illegal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == err) {
|
||||
/* Search if there are some non-printable characters */
|
||||
for (cp = field; '\0' != *cp; cp++) {
|
||||
if (!isprint (*cp)) {
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
/* Search if there are non-printable or control characters */
|
||||
for (cp = field; '\0' != *cp; cp++) {
|
||||
unsigned char c = *cp;
|
||||
if (!isprint (c)) {
|
||||
err = 1;
|
||||
}
|
||||
if (iscntrl (c)) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +73,7 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
|
||||
|
||||
printf ("\t%s [%s]: ", prompt, buf);
|
||||
(void) fflush (stdout);
|
||||
if (fgets (newf, (int) maxsize, stdin) != newf) {
|
||||
if (fgets (newf, maxsize, stdin) != newf) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,17 +90,16 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
|
||||
* entering a space. --marekm
|
||||
*/
|
||||
|
||||
while (--cp >= newf && isspace (*cp));
|
||||
cp++;
|
||||
while (newf < cp && isspace (cp[-1])) {
|
||||
cp--;
|
||||
}
|
||||
*cp = '\0';
|
||||
|
||||
cp = newf;
|
||||
while (('\0' != *cp) && isspace (*cp)) {
|
||||
while (isspace (*cp)) {
|
||||
cp++;
|
||||
}
|
||||
|
||||
strncpy (buf, cp, maxsize - 1);
|
||||
buf[maxsize - 1] = '\0';
|
||||
strcpy (buf, cp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 2008 - 2011, Nicolas François
|
||||
* Copyright (c) 2014, Red Hat, Inc.
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
|
||||
* SPDX-FileCopyrightText: 2014, Red Hat, Inc.
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -35,9 +12,11 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "groupio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* get_ranges - Get the minimum and maximum ID ranges for the search
|
||||
@@ -62,32 +41,38 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
||||
*preferred_min = (gid_t) 1;
|
||||
|
||||
/* Get the minimum ID range from login.defs or default to 101 */
|
||||
*min_id = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL);
|
||||
*min_id = getdef_ulong ("SYS_GID_MIN", 101UL);
|
||||
|
||||
/*
|
||||
* If SYS_GID_MAX is unspecified, we should assume it to be one
|
||||
* less than the GID_MIN (which is reserved for non-system accounts)
|
||||
*/
|
||||
gid_def_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
|
||||
*max_id = (gid_t) getdef_ulong ("SYS_GID_MAX",
|
||||
(unsigned long) gid_def_max);
|
||||
gid_def_max = getdef_ulong ("GID_MIN", 1000UL) - 1;
|
||||
*max_id = getdef_ulong ("SYS_GID_MAX", gid_def_max);
|
||||
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SYS_GID_MIN (%lu), "
|
||||
"GID_MIN (%lu), SYS_GID_MAX (%lu)\n"),
|
||||
Prog, (unsigned long) *min_id,
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("GID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
/*
|
||||
* Zero is reserved for root and the allocation algorithm does not
|
||||
* work right with it.
|
||||
*/
|
||||
if (*min_id == 0) {
|
||||
*min_id = (gid_t) 1;
|
||||
}
|
||||
} else {
|
||||
/* Non-system groups */
|
||||
|
||||
/* Get the values from login.defs or use reasonable defaults */
|
||||
*min_id = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
|
||||
*max_id = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
|
||||
*min_id = getdef_ulong ("GID_MIN", 1000UL);
|
||||
*max_id = getdef_ulong ("GID_MAX", 60000UL);
|
||||
|
||||
/*
|
||||
* The preferred minimum should match the standard ID minimum
|
||||
@@ -97,10 +82,10 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
||||
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: GID_MIN (%lu), "
|
||||
"GID_MAX (%lu)\n"),
|
||||
Prog, (unsigned long) *min_id,
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -114,19 +99,25 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
||||
*
|
||||
* On success, return 0
|
||||
* If the ID is in use, return EEXIST
|
||||
* If the ID might clash with -1, return EINVAL
|
||||
* If the ID is outside the range, return ERANGE
|
||||
* In other cases, return errno from getgrgid()
|
||||
*/
|
||||
static int check_gid (const gid_t gid,
|
||||
const gid_t gid_min,
|
||||
const gid_t gid_max,
|
||||
bool *used_gids)
|
||||
const bool *used_gids)
|
||||
{
|
||||
/* First test that the preferred ID is in the range */
|
||||
if (gid < gid_min || gid > gid_max) {
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
/* Check for compatibility with 16b and 32b gid_t error codes */
|
||||
if (gid == UINT16_MAX || gid == UINT32_MAX) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether we already detected this GID
|
||||
* using the gr_next() loop
|
||||
@@ -157,7 +148,7 @@ static int check_gid (const gid_t gid,
|
||||
* [GID_MIN:GID_MAX] range.
|
||||
* This ID should be higher than all the used GID, but if not possible,
|
||||
* the lowest unused ID in the range will be returned.
|
||||
*
|
||||
*
|
||||
* Return 0 on success, -1 if no unused GIDs are available.
|
||||
*/
|
||||
int find_new_gid (bool sys_group,
|
||||
@@ -198,10 +189,10 @@ int find_new_gid (bool sys_group,
|
||||
* gr_locate_gid() found the GID in an as-yet uncommitted
|
||||
* entry. We'll proceed below and auto-set a GID.
|
||||
*/
|
||||
} else if (result == EEXIST || result == ERANGE) {
|
||||
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
|
||||
/*
|
||||
* Continue on below. At this time, we won't
|
||||
* treat these two cases differently.
|
||||
* treat these three cases differently.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
@@ -213,10 +204,10 @@ int find_new_gid (bool sys_group,
|
||||
* more likely to want to stop and address the
|
||||
* issue.
|
||||
*/
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Encountered error attempting to use "
|
||||
"preferred GID: %s\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -241,14 +232,13 @@ int find_new_gid (bool sys_group,
|
||||
*/
|
||||
|
||||
/* Create an array to hold all of the discovered GIDs */
|
||||
used_gids = malloc (sizeof (bool) * (gid_max +1));
|
||||
used_gids = CALLOC (gid_max + 1, bool);
|
||||
if (NULL == used_gids) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to allocate memory: %s\n"),
|
||||
Prog, strerror (errno));
|
||||
log_get_progname(), strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
memset (used_gids, false, sizeof (bool) * (gid_max + 1));
|
||||
|
||||
/* First look for the lowest and highest value in the local database */
|
||||
(void) gr_rewind ();
|
||||
@@ -312,8 +302,11 @@ int find_new_gid (bool sys_group,
|
||||
*gid = id;
|
||||
free (used_gids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This GID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -323,10 +316,10 @@ int find_new_gid (bool sys_group,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique system GID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available GIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -355,8 +348,11 @@ int find_new_gid (bool sys_group,
|
||||
*gid = id;
|
||||
free (used_gids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This GID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -366,10 +362,10 @@ int find_new_gid (bool sys_group,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique system GID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available GIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -415,8 +411,11 @@ int find_new_gid (bool sys_group,
|
||||
*gid = id;
|
||||
free (used_gids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This GID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -426,10 +425,10 @@ int find_new_gid (bool sys_group,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique GID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available GIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -458,8 +457,11 @@ int find_new_gid (bool sys_group,
|
||||
*gid = id;
|
||||
free (used_gids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This GID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -469,10 +471,10 @@ int find_new_gid (bool sys_group,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique GID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available GIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -488,9 +490,9 @@ int find_new_gid (bool sys_group,
|
||||
}
|
||||
|
||||
/* The code reached here and found no available IDs in the range */
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique GID (no more available GIDs)\n"),
|
||||
Prog);
|
||||
log_get_progname());
|
||||
SYSLOG ((LOG_WARN, "no more available GIDs on the system"));
|
||||
free (used_gids);
|
||||
return -1;
|
||||
64
lib/find_new_sub_gids.c
Normal file
64
lib/find_new_sub_gids.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012 Eric Biederman
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "subordinateio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* find_new_sub_gids - Find a new unused range of GIDs.
|
||||
*
|
||||
* If successful, find_new_sub_gids provides a range of unused
|
||||
* user IDs in the [SUB_GID_MIN:SUB_GID_MAX] range.
|
||||
*
|
||||
* Return 0 on success, -1 if no unused GIDs are available.
|
||||
*/
|
||||
int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
|
||||
{
|
||||
unsigned long min, max;
|
||||
unsigned long count;
|
||||
gid_t start;
|
||||
|
||||
assert (range_start != NULL);
|
||||
assert (range_count != NULL);
|
||||
|
||||
min = getdef_ulong ("SUB_GID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
|
||||
count = getdef_ulong ("SUB_GID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SUB_GID_MIN (%lu),"
|
||||
" SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"),
|
||||
log_get_progname(), min, max, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
start = sub_gid_find_free_range(min, max, count);
|
||||
if (start == (gid_t)-1) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique subordinate GID range\n"),
|
||||
log_get_progname());
|
||||
SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system"));
|
||||
return -1;
|
||||
}
|
||||
*range_start = start;
|
||||
*range_count = count;
|
||||
return 0;
|
||||
}
|
||||
#else /* !ENABLE_SUBIDS */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* !ENABLE_SUBIDS */
|
||||
|
||||
64
lib/find_new_sub_uids.c
Normal file
64
lib/find_new_sub_uids.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012 Eric Biederman
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "subordinateio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* find_new_sub_uids - Find a new unused range of UIDs.
|
||||
*
|
||||
* If successful, find_new_sub_uids provides a range of unused
|
||||
* user IDs in the [SUB_UID_MIN:SUB_UID_MAX] range.
|
||||
*
|
||||
* Return 0 on success, -1 if no unused UIDs are available.
|
||||
*/
|
||||
int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
|
||||
{
|
||||
unsigned long min, max;
|
||||
unsigned long count;
|
||||
uid_t start;
|
||||
|
||||
assert (range_start != NULL);
|
||||
assert (range_count != NULL);
|
||||
|
||||
min = getdef_ulong ("SUB_UID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
|
||||
count = getdef_ulong ("SUB_UID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SUB_UID_MIN (%lu),"
|
||||
" SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"),
|
||||
log_get_progname(), min, max, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
start = sub_uid_find_free_range(min, max, count);
|
||||
if (start == (uid_t)-1) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique subordinate UID range\n"),
|
||||
log_get_progname());
|
||||
SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system"));
|
||||
return -1;
|
||||
}
|
||||
*range_start = start;
|
||||
*range_count = count;
|
||||
return 0;
|
||||
}
|
||||
#else /* !ENABLE_SUBIDS */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* !ENABLE_SUBIDS */
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 2008 - 2011, Nicolas François
|
||||
* Copyright (c) 2014, Red Hat, Inc.
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
|
||||
* SPDX-FileCopyrightText: 2014, Red Hat, Inc.
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -35,9 +12,11 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
/*
|
||||
* get_ranges - Get the minimum and maximum ID ranges for the search
|
||||
@@ -62,32 +41,38 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
||||
*preferred_min = (uid_t) 1;
|
||||
|
||||
/* Get the minimum ID range from login.defs or default to 101 */
|
||||
*min_id = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL);
|
||||
*min_id = getdef_ulong ("SYS_UID_MIN", 101UL);
|
||||
|
||||
/*
|
||||
* If SYS_UID_MAX is unspecified, we should assume it to be one
|
||||
* less than the UID_MIN (which is reserved for non-system accounts)
|
||||
*/
|
||||
uid_def_max = (uid_t) getdef_ulong ("UID_MIN", 1000UL) - 1;
|
||||
*max_id = (uid_t) getdef_ulong ("SYS_UID_MAX",
|
||||
(unsigned long) uid_def_max);
|
||||
uid_def_max = getdef_ulong ("UID_MIN", 1000UL) - 1;
|
||||
*max_id = getdef_ulong ("SYS_UID_MAX", uid_def_max);
|
||||
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SYS_UID_MIN (%lu), "
|
||||
"UID_MIN (%lu), SYS_UID_MAX (%lu)\n"),
|
||||
Prog, (unsigned long) *min_id,
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("UID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
/*
|
||||
* Zero is reserved for root and the allocation algorithm does not
|
||||
* work right with it.
|
||||
*/
|
||||
if (*min_id == 0) {
|
||||
*min_id = (uid_t) 1;
|
||||
}
|
||||
} else {
|
||||
/* Non-system users */
|
||||
|
||||
/* Get the values from login.defs or use reasonable defaults */
|
||||
*min_id = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||
*max_id = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||
*min_id = getdef_ulong ("UID_MIN", 1000UL);
|
||||
*max_id = getdef_ulong ("UID_MAX", 60000UL);
|
||||
|
||||
/*
|
||||
* The preferred minimum should match the standard ID minimum
|
||||
@@ -97,10 +82,10 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
||||
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: UID_MIN (%lu), "
|
||||
"UID_MAX (%lu)\n"),
|
||||
Prog, (unsigned long) *min_id,
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -114,19 +99,25 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
||||
*
|
||||
* On success, return 0
|
||||
* If the ID is in use, return EEXIST
|
||||
* If the ID might clash with -1, return EINVAL
|
||||
* If the ID is outside the range, return ERANGE
|
||||
* In other cases, return errno from getpwuid()
|
||||
*/
|
||||
static int check_uid(const uid_t uid,
|
||||
const uid_t uid_min,
|
||||
const uid_t uid_max,
|
||||
bool *used_uids)
|
||||
const bool *used_uids)
|
||||
{
|
||||
/* First test that the preferred ID is in the range */
|
||||
if (uid < uid_min || uid > uid_max) {
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
/* Check for compatibility with 16b and 32b uid_t error codes */
|
||||
if (uid == UINT16_MAX || uid == UINT32_MAX) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether we already detected this UID
|
||||
* using the pw_next() loop
|
||||
@@ -157,7 +148,7 @@ static int check_uid(const uid_t uid,
|
||||
* [UID_MIN:UID_MAX] range.
|
||||
* This ID should be higher than all the used UID, but if not possible,
|
||||
* the lowest unused ID in the range will be returned.
|
||||
*
|
||||
*
|
||||
* Return 0 on success, -1 if no unused UIDs are available.
|
||||
*/
|
||||
int find_new_uid(bool sys_user,
|
||||
@@ -198,10 +189,10 @@ int find_new_uid(bool sys_user,
|
||||
* pw_locate_uid() found the UID in an as-yet uncommitted
|
||||
* entry. We'll proceed below and auto-set an UID.
|
||||
*/
|
||||
} else if (result == EEXIST || result == ERANGE) {
|
||||
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
|
||||
/*
|
||||
* Continue on below. At this time, we won't
|
||||
* treat these two cases differently.
|
||||
* treat these three cases differently.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
@@ -213,10 +204,10 @@ int find_new_uid(bool sys_user,
|
||||
* more likely to want to stop and address the
|
||||
* issue.
|
||||
*/
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Encountered error attempting to use "
|
||||
"preferred UID: %s\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -241,11 +232,11 @@ int find_new_uid(bool sys_user,
|
||||
*/
|
||||
|
||||
/* Create an array to hold all of the discovered UIDs */
|
||||
used_uids = malloc (sizeof (bool) * (uid_max +1));
|
||||
used_uids = MALLOC(uid_max + 1, bool);
|
||||
if (NULL == used_uids) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to allocate memory: %s\n"),
|
||||
Prog, strerror (errno));
|
||||
log_get_progname(), strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
memset (used_uids, false, sizeof (bool) * (uid_max + 1));
|
||||
@@ -312,8 +303,11 @@ int find_new_uid(bool sys_user,
|
||||
*uid = id;
|
||||
free (used_uids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This UID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -323,10 +317,10 @@ int find_new_uid(bool sys_user,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique system UID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available UIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -355,8 +349,11 @@ int find_new_uid(bool sys_user,
|
||||
*uid = id;
|
||||
free (used_uids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This UID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -366,10 +363,10 @@ int find_new_uid(bool sys_user,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique system UID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG((LOG_ERR,
|
||||
"Error checking available UIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -415,8 +412,11 @@ int find_new_uid(bool sys_user,
|
||||
*uid = id;
|
||||
free (used_uids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This UID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -426,10 +426,10 @@ int find_new_uid(bool sys_user,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique UID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available UIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -458,8 +458,11 @@ int find_new_uid(bool sys_user,
|
||||
*uid = id;
|
||||
free (used_uids);
|
||||
return 0;
|
||||
} else if (result == EEXIST) {
|
||||
/* This UID is in use, we'll continue to the next */
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* An unexpected error occurred.
|
||||
@@ -469,10 +472,10 @@ int find_new_uid(bool sys_user,
|
||||
*
|
||||
*/
|
||||
if (!nospam) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique UID (%s). "
|
||||
"Suppressing additional messages.\n"),
|
||||
Prog, strerror (result));
|
||||
log_get_progname(), strerror (result));
|
||||
SYSLOG ((LOG_ERR,
|
||||
"Error checking available UIDs: %s",
|
||||
strerror (result)));
|
||||
@@ -488,9 +491,9 @@ int find_new_uid(bool sys_user,
|
||||
}
|
||||
|
||||
/* The code reached here and found no available IDs in the range */
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Can't get unique UID (no more available UIDs)\n"),
|
||||
Prog);
|
||||
log_get_progname());
|
||||
SYSLOG ((LOG_WARN, "no more available UIDs on the system"));
|
||||
free (used_uids);
|
||||
return -1;
|
||||
33
lib/fputsx.c
33
lib/fputsx.c
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
|
||||
* Copyright (c) 2005 , Tomasz Kłoczko
|
||||
* Copyright (c) 2008 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
30
lib/freezero.c
Normal file
30
lib/freezero.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* $OpenBSD: malloc.c,v 1.267 2020/11/23 15:42:11 otto Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2010, 2011, 2016 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
freezero(void *ptr, size_t sz)
|
||||
{
|
||||
/* This is legal. */
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
explicit_bzero(ptr, sz);
|
||||
free(ptr);
|
||||
}
|
||||
34
lib/freezero.h
Normal file
34
lib/freezero.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright © 2005 Aurelien Jarno
|
||||
* Copyright © 2006 Robert Millan
|
||||
* Copyright © 2008-2011 Guillem Jover <guillem@hadrons.org>
|
||||
*
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE 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. IN NO EVENT SHALL
|
||||
* THE AUTHOR 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 LIBBSD_FREEZERO_H
|
||||
#define LIBBSD_FREEZERO_H
|
||||
|
||||
void freezero(void *ptr, size_t size);
|
||||
|
||||
#endif
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2009 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2009 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -48,7 +25,7 @@ int get_gid (const char *gidstr, gid_t *gid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*gid = (gid_t)val;
|
||||
*gid = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
100
lib/get_pid.c
100
lib/get_pid.c
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2009 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2009 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -33,6 +10,9 @@
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int get_pid (const char *pidstr, pid_t *pid)
|
||||
{
|
||||
@@ -44,11 +24,79 @@ int get_pid (const char *pidstr, pid_t *pid)
|
||||
if ( ('\0' == *pidstr)
|
||||
|| ('\0' != *endptr)
|
||||
|| (ERANGE == errno)
|
||||
|| (val < 1)
|
||||
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pid = (pid_t)val;
|
||||
*pid = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If use passed in fd:4 as an argument, then return the
|
||||
* value '4', the fd to use.
|
||||
* On error, return -1.
|
||||
*/
|
||||
int get_pidfd_from_fd(const char *pidfdstr)
|
||||
{
|
||||
long long int val;
|
||||
char *endptr;
|
||||
struct stat st;
|
||||
dev_t proc_st_dev, proc_st_rdev;
|
||||
|
||||
errno = 0;
|
||||
val = strtoll (pidfdstr, &endptr, 10);
|
||||
if ( ('\0' == *pidfdstr)
|
||||
|| ('\0' != *endptr)
|
||||
|| (ERANGE == errno)
|
||||
|| (val < 0)
|
||||
|| (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stat("/proc/self/uid_map", &st) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
proc_st_dev = st.st_dev;
|
||||
proc_st_rdev = st.st_rdev;
|
||||
|
||||
if (fstat(val, &st) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (st.st_dev != proc_st_dev || st.st_rdev != proc_st_rdev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
int open_pidfd(const char *pidstr)
|
||||
{
|
||||
int proc_dir_fd;
|
||||
int written;
|
||||
char proc_dir_name[32];
|
||||
pid_t target;
|
||||
|
||||
if (get_pid(pidstr, &target) == 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
|
||||
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
|
||||
target);
|
||||
if ((written <= 0) || ((size_t)written >= sizeof(proc_dir_name))) {
|
||||
fprintf(stderr, "snprintf of proc path failed for %u: %s\n",
|
||||
target, strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
|
||||
if (proc_dir_fd < 0) {
|
||||
fprintf(stderr, _("Could not open proc directory for target %u: %s\n"),
|
||||
target, strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
return proc_dir_fd;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2009 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2009 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -48,7 +25,7 @@ int get_uid (const char *uidstr, uid_t *uid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*uid = (uid_t)val;
|
||||
*uid = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
16
lib/getdate.h
Normal file
16
lib/getdate.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _GETDATE_H_
|
||||
#define _GETDATE_H_
|
||||
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
|
||||
time_t get_date (const char *p, /*@null@*/const time_t *now);
|
||||
#endif
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# ifdef FORCE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Since the code of getdate.y is not included in the Emacs executable
|
||||
@@ -31,37 +28,14 @@
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
# define IN_CTYPE_DOMAIN(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
|
||||
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
|
||||
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
|
||||
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
|
||||
/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
|
||||
- Its arg may be any int or unsigned int; it need not be an unsigned char.
|
||||
- It's guaranteed to evaluate its argument exactly once.
|
||||
- It's typically faster.
|
||||
Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
|
||||
only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
|
||||
it's important to use the locale's definition of `digit' even when the
|
||||
host does not conform to Posix. */
|
||||
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
|
||||
|
||||
#include "getdate.h"
|
||||
|
||||
#if defined (STDC_HEADERS)
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/* Some old versions of bison generate parsers that use bcopy.
|
||||
That loses on systems that don't provide the function, so we have
|
||||
to redefine it here. */
|
||||
#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
|
||||
#if !defined (HAVE_BCOPY) && !defined (bcopy)
|
||||
# define bcopy(from, to, len) memcpy ((to), (from), (len))
|
||||
#endif
|
||||
|
||||
@@ -651,7 +625,7 @@ static int LookupWord (char *buff)
|
||||
|
||||
/* Make it lowercase. */
|
||||
for (p = buff; '\0' != *p; p++)
|
||||
if (ISUPPER (*p))
|
||||
if (isupper (*p))
|
||||
*p = tolower (*p);
|
||||
|
||||
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
|
||||
@@ -732,7 +706,7 @@ static int LookupWord (char *buff)
|
||||
}
|
||||
|
||||
/* Military timezones. */
|
||||
if (buff[1] == '\0' && ISALPHA (*buff))
|
||||
if (buff[1] == '\0' && isalpha (*buff))
|
||||
{
|
||||
for (tp = MilitaryTable; tp->name; tp++)
|
||||
if (strcmp (buff, tp->name) == 0)
|
||||
@@ -771,30 +745,30 @@ yylex (void)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (ISSPACE (*yyInput))
|
||||
while (isspace (*yyInput))
|
||||
yyInput++;
|
||||
|
||||
if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
|
||||
if (isdigit (c = *yyInput) || c == '-' || c == '+')
|
||||
{
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
sign = c == '-' ? -1 : 1;
|
||||
if (!ISDIGIT (*++yyInput))
|
||||
if (!isdigit (*++yyInput))
|
||||
/* skip the '-' sign */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
|
||||
for (yylval.Number = 0; isdigit (c = *yyInput++);)
|
||||
yylval.Number = 10 * yylval.Number + c - '0';
|
||||
yyInput--;
|
||||
if (sign < 0)
|
||||
yylval.Number = -yylval.Number;
|
||||
return (0 != sign) ? tSNUMBER : tUNUMBER;
|
||||
}
|
||||
if (ISALPHA (c))
|
||||
if (isalpha (c))
|
||||
{
|
||||
for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
|
||||
for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
|
||||
if (p < &buff[sizeof buff - 1])
|
||||
*p++ = c;
|
||||
*p = '\0';
|
||||
97
lib/getdef.c
97
lib/getdef.c
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
||||
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2008, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2002 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -36,6 +13,7 @@
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@@ -43,7 +21,11 @@
|
||||
#ifdef USE_ECONF
|
||||
#include <libeconf.h>
|
||||
#endif
|
||||
|
||||
#include "alloc.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog_internal.h"
|
||||
|
||||
/*
|
||||
* A configuration item definition.
|
||||
*/
|
||||
@@ -154,10 +136,8 @@ static struct itemdef def_table[] = {
|
||||
#ifndef USE_PAM
|
||||
PAMDEFS
|
||||
#endif
|
||||
#ifdef USE_SYSLOG
|
||||
{"SYSLOG_SG_ENAB", NULL},
|
||||
{"SYSLOG_SU_ENAB", NULL},
|
||||
#endif
|
||||
#ifdef WITH_TCB
|
||||
{"TCB_AUTH_GROUP", NULL},
|
||||
{"TCB_SYMLINKS", NULL},
|
||||
@@ -215,7 +195,7 @@ static void def_load (void);
|
||||
}
|
||||
|
||||
d = def_find (item);
|
||||
return ((NULL == d)? (const char *) NULL : d->value);
|
||||
return (NULL == d) ? NULL : d->value;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +253,7 @@ int getdef_num (const char *item, int dflt)
|
||||
return dflt;
|
||||
}
|
||||
|
||||
return (int) val;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +288,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
|
||||
return dflt;
|
||||
}
|
||||
|
||||
return (unsigned int) val;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@@ -367,7 +347,6 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt)
|
||||
}
|
||||
|
||||
if (getulong (d->value, &val) == 0) {
|
||||
/* FIXME: we should have a getulong */
|
||||
fprintf (shadow_logfd,
|
||||
_("configuration error - cannot parse %s value: '%s'"),
|
||||
item, d->value);
|
||||
@@ -411,10 +390,7 @@ int putdef_str (const char *name, const char *value)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != d->value) {
|
||||
free (d->value);
|
||||
}
|
||||
|
||||
free (d->value);
|
||||
d->value = cp;
|
||||
return 0;
|
||||
}
|
||||
@@ -456,7 +432,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
|
||||
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
|
||||
|
||||
out:
|
||||
return (struct itemdef *) NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -472,14 +448,14 @@ void setdef_config_file (const char* file)
|
||||
char* cp;
|
||||
|
||||
len = strlen(file) + strlen(sysconfdir) + 2;
|
||||
cp = malloc(len);
|
||||
cp = MALLOC(len, char);
|
||||
if (cp == NULL)
|
||||
exit (13);
|
||||
snprintf(cp, len, "%s/%s", file, sysconfdir);
|
||||
sysconfdir = cp;
|
||||
#ifdef VENDORDIR
|
||||
len = strlen(file) + strlen(vendordir) + 2;
|
||||
cp = malloc(len);
|
||||
cp = MALLOC(len, char);
|
||||
if (cp == NULL)
|
||||
exit (13);
|
||||
snprintf(cp, len, "%s/%s", file, vendordir);
|
||||
@@ -496,18 +472,13 @@ void setdef_config_file (const char* file)
|
||||
* Loads the user-configured options from the default configuration file
|
||||
*/
|
||||
|
||||
#ifdef USE_ECONF
|
||||
static void def_load (void)
|
||||
{
|
||||
#ifdef USE_ECONF
|
||||
econf_file *defs_file = NULL;
|
||||
econf_err error;
|
||||
char **keys;
|
||||
size_t key_number;
|
||||
#else
|
||||
int i;
|
||||
FILE *fp;
|
||||
char buf[1024], *name, *value, *s;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
@@ -515,8 +486,6 @@ static void def_load (void)
|
||||
*/
|
||||
def_loaded = true;
|
||||
|
||||
#ifdef USE_ECONF
|
||||
|
||||
error = econf_readDirs (&defs_file, vendordir, sysconfdir, "login", "defs", " \t", "#");
|
||||
if (error) {
|
||||
if (error == ECONF_NOFILE)
|
||||
@@ -536,7 +505,12 @@ static void def_load (void)
|
||||
for (size_t i = 0; i < key_number; i++) {
|
||||
char *value;
|
||||
|
||||
econf_getStringValue(defs_file, NULL, keys[i], &value);
|
||||
error = econf_getStringValue(defs_file, NULL, keys[i], &value);
|
||||
if (error) {
|
||||
SYSLOG ((LOG_CRIT, "failed reading key %zu from econf [%s]",
|
||||
i, econf_errString(error)));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the value in def_table.
|
||||
@@ -546,11 +520,26 @@ static void def_load (void)
|
||||
* syslog. The tools will just use their default values.
|
||||
*/
|
||||
(void)putdef_str (keys[i], value);
|
||||
|
||||
free(value);
|
||||
}
|
||||
|
||||
econf_free (keys);
|
||||
econf_free (defs_file);
|
||||
#else
|
||||
}
|
||||
#else /* USE_ECONF */
|
||||
static void def_load (void)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
char buf[1024], *name, *value, *s;
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
* (do it early to prevent recursion in putdef_str())
|
||||
*/
|
||||
def_loaded = true;
|
||||
|
||||
/*
|
||||
* Open the configuration definitions file.
|
||||
*/
|
||||
@@ -568,12 +557,12 @@ static void def_load (void)
|
||||
/*
|
||||
* Go through all of the lines in the file.
|
||||
*/
|
||||
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
|
||||
while (fgets (buf, sizeof (buf), fp) != NULL) {
|
||||
|
||||
/*
|
||||
* Trim trailing whitespace.
|
||||
*/
|
||||
for (i = (int) strlen (buf) - 1; i >= 0; --i) {
|
||||
for (i = (ptrdiff_t) strlen (buf) - 1; i >= 0; --i) {
|
||||
if (!isspace (buf[i])) {
|
||||
break;
|
||||
}
|
||||
@@ -614,8 +603,8 @@ static void def_load (void)
|
||||
}
|
||||
|
||||
(void) fclose (fp);
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_ECONF */
|
||||
|
||||
|
||||
#ifdef CKDEFS
|
||||
|
||||
33
lib/getdef.h
33
lib/getdef.h
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
||||
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2008 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2002 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _GETDEF_H
|
||||
#define _GETDEF_H
|
||||
|
||||
43
lib/getgr_nam_gid.c
Normal file
43
lib/getgr_nam_gid.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
/*
|
||||
* getgr_nam_gid - Return a pointer to the group specified by a string.
|
||||
* The string may be a valid GID or a valid groupname.
|
||||
* If the group does not exist on the system, NULL is returned.
|
||||
*/
|
||||
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname)
|
||||
{
|
||||
long long int gid;
|
||||
char *endptr;
|
||||
|
||||
if (NULL == grname) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
gid = strtoll (grname, &endptr, 10);
|
||||
if ( ('\0' != *grname)
|
||||
&& ('\0' == *endptr)
|
||||
&& (ERANGE != errno)
|
||||
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
|
||||
return xgetgrgid (gid);
|
||||
}
|
||||
return xgetgrnam (grname);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 - 2009, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -1,30 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 , Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* 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. The name of the copyright holders or contributors may not 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
|
||||
* HOLDERS 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.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -48,7 +25,7 @@
|
||||
* If the range is valid, getrange returns 1.
|
||||
* If the range is not valid, getrange returns 0.
|
||||
*/
|
||||
int getrange (char *range,
|
||||
int getrange (const char *range,
|
||||
unsigned long *min, bool *has_min,
|
||||
unsigned long *max, bool *has_max)
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user