23 #include <sys/types.h>
24 #include <sys/socket.h>
29 #include <tqcstring.h>
34 #include <kstandarddirs.h>
35 #include <tdeapplication.h>
40 class TDEsuClient::TDEsuClientPrivate {
46 #define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \
47 + strlen ((ptr)->sun_path))
50 TDEsuClient::TDEsuClient()
54 TQCString display(getenv(
"DISPLAY"));
55 if (display.isEmpty())
57 kdWarning(900) << k_lineinfo <<
"$DISPLAY is not set\n";
62 display.replace(TQRegExp(
"\\.[0-9]+$"),
"");
64 TQCString display(
"QWS");
67 sock = TQFile::encodeName(locateLocal(
"socket", TQString(
"tdesud_%1").arg(display.data())));
68 d =
new TDEsuClientPrivate;
73 TDEsuClient::~TDEsuClient()
80 int TDEsuClient::connect()
84 if (access(sock, R_OK|W_OK))
90 sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
93 kdWarning(900) << k_lineinfo <<
"socket(): " << perror <<
"\n";
96 struct sockaddr_un addr;
97 addr.sun_family = AF_UNIX;
98 strcpy(addr.sun_path, sock);
100 if (::connect(sockfd, (
struct sockaddr *) &addr, SUN_LEN(&addr)) < 0)
102 kdWarning(900) << k_lineinfo <<
"connect():" << perror << endl;
103 close(sockfd); sockfd = -1;
107 #if !defined(SO_PEERCRED) || !defined(HAVE_STRUCT_UCRED)
108 # if defined(HAVE_GETPEEREID)
112 if (getpeereid(sockfd, &euid, &egid) == 0)
114 if (euid != getuid())
116 kdWarning(900) <<
"socket not owned by me! socket uid = " << euid << endl;
117 close(sockfd); sockfd = -1;
123 # warning "Using sloppy security checks"
130 if (KDE_lstat(sock, &s)!=0)
132 kdWarning(900) <<
"stat failed (" << sock <<
")" << endl;
133 close(sockfd); sockfd = -1;
136 if (s.st_uid != getuid())
138 kdWarning(900) <<
"socket not owned by me! socket uid = " << s.st_uid << endl;
139 close(sockfd); sockfd = -1;
142 if (!S_ISSOCK(s.st_mode))
144 kdWarning(900) <<
"socket is not a socket (" << sock <<
")" << endl;
145 close(sockfd); sockfd = -1;
151 socklen_t siz =
sizeof(cred);
154 if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0)
156 if (cred.uid != getuid())
158 kdWarning(900) <<
"socket not owned by me! socket uid = " << cred.uid << endl;
159 close(sockfd); sockfd = -1;
168 TQCString TDEsuClient::escape(
const TQCString &str)
170 TQCString copy = str;
172 while ((n = copy.find(
"\\", n)) != -1)
174 copy.insert(n,
'\\');
178 while ((n = copy.find(
"\"", n)) != -1)
180 copy.insert(n,
'\\');
188 int TDEsuClient::command(
const TQCString &cmd, TQCString *result)
193 if (send(sockfd, cmd, cmd.length(), 0) != (
int) cmd.length())
197 int nbytes = recv(sockfd, buf, 1023, 0);
200 kdWarning(900) << k_lineinfo <<
"no reply from daemon\n";
203 buf[nbytes] =
'\000';
205 TQCString reply = buf;
206 if (reply.left(2) !=
"OK")
210 *result = reply.mid(3, reply.length()-4);
216 TQCString cmd =
"PASS ";
219 cmd += TQCString().setNum(timeout);
224 int TDEsuClient::exec(
const TQCString &prog,
const TQCString &user,
const TQCString &options,
const QCStringList &env)
231 if (!options.isEmpty() || !env.isEmpty())
234 cmd += escape(options);
235 for(QCStringList::ConstIterator it = env.begin();
236 it != env.end(); ++it)
248 TQCString cmd =
"HOST ";
257 cmd.sprintf(
"PRIO %d\n", prio);
264 cmd.sprintf(
"SCHD %d\n", sched);
270 TQCString cmd =
"DEL ";
278 const TQCString &group)
280 TQCString cmd =
"SET ";
283 cmd += escape(value);
285 cmd += escape(group);
287 cmd += TQCString().setNum(timeout);
294 TQCString cmd =
"GET ";
298 command(cmd, &reply);
304 TQCString cmd =
"GETK ";
305 cmd += escape(group);
308 command(cmd, &reply);
310 TQValueList<TQCString> list;
311 if( !reply.isEmpty() )
316 pos = reply.find(
'\007', index );
320 list.append( reply );
322 list.append( reply.mid(index) );
327 list.append( reply.mid(index, pos-index) );
337 TQCString cmd =
"CHKG ";
338 cmd += escape(group);
340 if( command(cmd) == -1 )
347 TQCString cmd =
"DELV ";
355 TQCString cmd =
"DELG ";
356 cmd += escape(group);
363 TQCString cmd =
"DELS ";
364 cmd += escape(special_key);
371 return command(
"PING\n");
377 if (command(
"EXIT\n", &result) != 0)
380 return result.toLong();
385 return command(
"STOP\n");
388 static TQString findDaemon()
390 TQString daemon = locate(
"bin",
"tdesud");
391 if (daemon.isEmpty())
392 daemon = TDEStandardDirs::findExe(
"tdesud");
394 if (daemon.isEmpty())
396 kdWarning(900) << k_lineinfo <<
"daemon not found\n";
403 if (d->daemon.isEmpty())
404 d->daemon = findDaemon();
405 if (d->daemon.isEmpty())
408 KDE_struct_stat sbuf;
409 if (KDE_stat(TQFile::encodeName(d->daemon), &sbuf) < 0)
411 kdWarning(900) << k_lineinfo <<
"stat(): " << perror <<
"\n";
414 return (sbuf.st_mode & S_ISGID);
419 if (d->daemon.isEmpty())
420 d->daemon = findDaemon();
421 if (d->daemon.isEmpty())
425 kdWarning(900) << k_lineinfo <<
"tdesud not setgid!\n";
432 int ret = kapp->tdeinitExecWait(d->daemon);
int delVar(const TQCString &key)
Delete a persistent variable.
int stopServer()
Stop the daemon.
int delGroup(const TQCString &group)
Delete all persistent variables in a group.
TQCString getVar(const TQCString &key)
Get a persistent variable.
int setPriority(int priority)
Set the desired priority (optional), see StubProcess.
int delCommand(const TQCString &command, const TQCString &user)
Remove a password for a user/command.
int startServer()
Try to start up tdesud.
int exitCode()
Wait for the last command to exit and return the exit code.
int setHost(const TQCString &host)
Set the target host (optional).
TQValueList< TQCString > getKeys(const TQCString &group)
Gets all the keys that are membes of the given group.
int exec(const TQCString &command, const TQCString &user, const TQCString &options=0, const QCStringList &env=QCStringList())
Lets tdesud execute a command.
int delVars(const TQCString &special_key)
Delete all persistent variables with the given key.
int setVar(const TQCString &key, const TQCString &value, int timeout=0, const TQCString &group=0)
Set a persistent variable.
bool isServerSGID()
Returns true if the server is safe (installed setgid), false otherwise.
int setScheduler(int scheduler)
Set the desired scheduler (optional), see StubProcess.
int setPass(const char *pass, int timeout)
Set root's password, lasts one session.
bool findGroup(const TQCString &group)
Returns true if the specified group exists is cached.