16 #include <config-kdesu.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
30 #include <QtCore/QBool>
31 #include <QtCore/QFile>
32 #include <QtCore/QRegExp>
43 class KDEsuClient::KDEsuClientPrivate {
45 KDEsuClientPrivate() : sockfd(-1) {}
52 #define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \
53 + strlen ((ptr)->sun_path))
57 :d(new KDEsuClientPrivate)
60 QString display = QString::fromLatin1(qgetenv(
"DISPLAY"));
61 if (display.isEmpty())
68 display.remove(QRegExp(
"\\.[0-9]+$"));
69 #elif defined(Q_WS_QWS)
70 QByteArray display(
"QWS");
72 QByteArray display(
"NODISPLAY");
76 QString(
"kdesud_").append(display)));
88 int KDEsuClient::connect()
92 if (
access(d->sock, R_OK|W_OK))
98 d->sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
104 struct sockaddr_un addr;
105 addr.sun_family = AF_UNIX;
106 strcpy(addr.sun_path, d->sock);
108 if (::connect(d->sockfd, (
struct sockaddr *) &addr,
SUN_LEN(&addr)) < 0)
111 close(d->sockfd); d->sockfd = -1;
115 #if !defined(SO_PEERCRED) || !defined(HAVE_STRUCT_UCRED)
116 # if defined(HAVE_GETPEEREID)
120 if (getpeereid(d->sockfd, &euid, &egid) == 0)
122 if (euid != getuid())
125 close(d->sockfd); d->sockfd = -1;
131 # warning "Using sloppy security checks"
138 if (KDE_lstat(d->sock, &s)!=0)
141 close(d->sockfd); d->sockfd = -1;
144 if (s.st_uid != getuid())
147 close(d->sockfd); d->sockfd = -1;
150 if (!S_ISSOCK(s.st_mode))
153 close(d->sockfd); d->sockfd = -1;
159 socklen_t siz =
sizeof(cred);
162 if (getsockopt(d->sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0)
164 if (cred.uid != getuid())
167 close(d->sockfd); d->sockfd = -1;
176 QByteArray KDEsuClient::escape(
const QByteArray &str)
179 copy.reserve(str.size() + 4);
181 for (
int i = 0; i < str.size(); i++) {
186 copy.append(c +
'@');
188 if (c ==
'\\' || c ==
'"')
197 int KDEsuClient::command(
const QByteArray &cmd, QByteArray *result)
202 if (send(d->sockfd, cmd, cmd.length(), 0) != (
int) cmd.length())
206 int nbytes = recv(d->sockfd, buf, 1023, 0);
212 buf[nbytes] =
'\000';
214 QByteArray reply = buf;
215 if (reply.left(2) !=
"OK")
219 *result = reply.mid(3, reply.length()-4);
225 QByteArray cmd =
"PASS ";
228 cmd += QByteArray().setNum(timeout);
240 if (!options.isEmpty() || !env.isEmpty())
243 cmd += escape(options);
244 for (
int i = 0; i < env.count(); ++i)
247 cmd += escape(env.at(i));
256 QByteArray cmd =
"HOST ";
266 cmd += QByteArray::number(prio);
275 cmd += QByteArray::number(sched);
282 QByteArray cmd =
"DEL ";
290 const QByteArray &group)
292 QByteArray cmd =
"SET ";
295 cmd += escape(value);
297 cmd += escape(group);
299 cmd += QByteArray().setNum(timeout);
306 QByteArray cmd =
"GET ";
310 command(cmd, &reply);
316 QByteArray cmd =
"GETK ";
317 cmd += escape(group);
320 command(cmd, &reply);
323 if( !reply.isEmpty() )
328 pos = reply.indexOf(
'\007', index );
332 list.append( reply );
334 list.append( reply.mid(index) );
339 list.append( reply.mid(index, pos-index) );
349 QByteArray cmd =
"CHKG ";
350 cmd += escape(group);
352 if( command(cmd) == -1 )
359 QByteArray cmd =
"DELV ";
367 QByteArray cmd =
"DELG ";
368 cmd += escape(group);
375 QByteArray cmd =
"DELS ";
376 cmd += escape(special_key);
383 return command(
"PING\n");
389 if (command(
"EXIT\n", &result) != 0)
392 return result.toInt();
397 return command(
"STOP\n");
403 if (daemon.isEmpty())
406 if (daemon.isEmpty())
415 if (d->daemon.isEmpty())
417 if (d->daemon.isEmpty())
420 KDE_struct_stat sbuf;
421 if (KDE::stat(d->daemon, &sbuf) < 0)
426 return (sbuf.st_mode & S_ISGID);
431 if (d->daemon.isEmpty())
433 if (d->daemon.isEmpty())