2 * kPPP: A pppd front end for the KDE project
6 * Copyright (C) 1997 Bernd Johannes Wuebben
7 * wuebben@math.cornell.edu
9 * This file was contributed by Mario Weilguni <mweilguni@sime.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with this program; if not, write to the Free
24 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <kmessagebox.h>
34 #include <sys/types.h>
36 #include <netinet/in.h>
39 #include <arpa/nameser.h>
44 #define _PATH_RESCONF "/etc/resolv.conf"
50 // initial effective uid (main.cpp)
53 // secure pppd location (opener.cpp)
54 extern const char* pppdPath();
56 // shamelessly stolen from pppd-2.3.5
57 /********************************************************************
59 * Internal routine to decode the version.modification.patch level
62 static void decode_version (const char *_buf
, int *version
,
63 int *modification
, int *patch
)
65 char *buffer
= qstrdup(_buf
);
67 *version
= (int) strtoul (buf
, &buf
, 10);
74 *modification
= (int) strtoul (buf
, &buf
, 10);
78 *patch
= (int) strtoul (buf
, &buf
, 10);
93 void pppdVersion(int *version
, int *modification
, int *patch
) {
98 *version
= *modification
= *patch
= 0;
101 if(!(pppd
= pppdPath()))
104 // call pppd with --version option
105 if(!(query
= new char[strlen(pppd
)+25]))
108 // had to add a dummy device to prevent a "no device specified
109 // and stdin is not a tty" error from newer pppd versions.
110 strcat(query
, " --version /dev/tty 2>&1");
112 FILE *output
= popen(query
, "r");
118 int size
= fread(buffer
, sizeof(char), 29, output
);
127 // find position of version number x.y.z
129 while(*p
&& !isdigit(*p
))
134 while(*p2
== '.' || isdigit(*p2
))
138 decode_version(p
, version
, modification
, patch
);
142 int uidFromName(const char *uname
) {
146 while((pw
= getpwent()) != NULL
) {
147 if(strcmp(uname
, pw
->pw_name
) == 0) {
148 int uid
= pw
->pw_uid
;
159 const char *homedirFromUid(uid_t uid
) {
164 while((pw
= getpwent()) != NULL
) {
165 if(pw
->pw_uid
== uid
) {
166 d
= strdup(pw
->pw_dir
);
177 const char* getHomeDir() {
178 static const char *hd
= 0;
179 static bool ranTest
= false;
181 hd
= homedirFromUid(getuid());
192 // Test pre-1: check if the user is allowed to dial-out
193 if(access("/etc/kppp.allow", R_OK
) == 0 && getuid() != 0) {
196 if((f
= fopen("/etc/kppp.allow", "r")) != NULL
) {
197 char buf
[2048]; // safe
198 while(f
!= NULL
&& !feof(f
)) {
199 if(fgets(buf
, sizeof(buf
), f
) != NULL
) {
203 if(s
[0] == '#' || s
.length() == 0)
206 if((uid_t
)uidFromName(QFile::encodeName(s
)) == getuid()) {
218 KMessageBox::error(0,
219 i18n("You are not allowed to dial out with "
220 "kppp.\nContact your system administrator."));
221 return TEST_CRITICAL
;
225 // Test 1: search the pppd binary
226 const char *f
= pppdPath();
229 KMessageBox::error(0,
230 i18n("Cannot find the PPP daemon.\n"
231 "Make sure that pppd is installed."));
235 // Test 2: check access to the pppd binary
238 if(access(f
, X_OK
) != 0 /* && geteuid() != 0 */) {
239 KMessageBox::error(0,
240 i18n("You do not have the permission "
242 "Contact your system administrator "
243 "and ask to get access to pppd."));
244 return TEST_CRITICAL
;
251 if(st
.st_uid
!= 0 || (st
.st_mode
& S_ISUID
) == 0) {
252 KMessageBox::error(0,
253 i18n("You do not have sufficient permission to run\n"
255 "Please make sure that kppp is owned by root "
256 "and has the SUID bit set.", f
));
262 // Test 5: check for existence of /etc/resolv.conf
263 if (access(_PATH_RESCONF
, R_OK
) != 0) {
264 QString file
= _PATH_RESCONF
" ";
265 QString msgstr
= i18n("%1 is missing or can not be read.\n"
266 "Ask your system administrator to create "
267 "this file (can be empty) with appropriate "
268 "read and write permissions.", file
);
269 KMessageBox::error(0, msgstr
);