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 setPriority(int priority)
Set the desired priority (optional), see StubProcess.
int setScheduler(int scheduler)
Set the desired scheduler (optional), see StubProcess.
bool isServerSGID()
Returns true if the server is safe (installed setgid), false otherwise.
TQValueList< TQCString > getKeys(const TQCString &group)
Gets all the keys that are membes of the given group.
int delGroup(const TQCString &group)
Delete all persistent variables in a group.
int delCommand(const TQCString &command, const TQCString &user)
Remove a password for a user/command.
int startServer()
Try to start up tdesud.
int setHost(const TQCString &host)
Set the target host (optional).
int setVar(const TQCString &key, const TQCString &value, int timeout=0, const TQCString &group=0)
Set a persistent variable.
int delVars(const TQCString &special_key)
Delete all persistent variables with the given key.
int stopServer()
Stop the daemon.
int exec(const TQCString &command, const TQCString &user, const TQCString &options=0, const QCStringList &env=QCStringList())
Lets tdesud execute a command.
bool findGroup(const TQCString &group)
Returns true if the specified group exists is cached.
TQCString getVar(const TQCString &key)
Get a persistent variable.
int setPass(const char *pass, int timeout)
Set root's password, lasts one session.
int delVar(const TQCString &key)
Delete a persistent variable.
int exitCode()
Wait for the last command to exit and return the exit code.