26 #include <sys/types.h>
27 #include <sys/socket.h>
32 #include <tqcstring.h>
37 #include <kstandarddirs.h>
38 #include <tdeapplication.h>
43 class TDEsuClient::TDEsuClientPrivate {
49 #define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \
50 + strlen ((ptr)->sun_path))
53 TDEsuClient::TDEsuClient()
57 TQCString display(getenv(
"DISPLAY"));
58 if (display.isEmpty())
60 kdWarning(900) << k_lineinfo <<
"$DISPLAY is not set\n";
65 display.replace(TQRegExp(
"\\.[0-9]+$"),
"");
67 TQCString display(
"QWS");
70 sock = TQFile::encodeName(locateLocal(
"socket", TQString(
"tdesud_%1").arg(display.data())));
71 d =
new TDEsuClientPrivate;
76 TDEsuClient::~TDEsuClient()
83 int TDEsuClient::connect()
87 if (access(sock, R_OK|W_OK))
93 sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
96 kdWarning(900) << k_lineinfo <<
"socket(): " << perror <<
"\n";
99 struct sockaddr_un addr;
100 addr.sun_family = AF_UNIX;
101 strcpy(addr.sun_path, sock);
103 if (::connect(sockfd, (
struct sockaddr *) &addr, SUN_LEN(&addr)) < 0)
105 kdWarning(900) << k_lineinfo <<
"connect():" << perror << endl;
106 close(sockfd); sockfd = -1;
110 #if !defined(SO_PEERCRED) || !defined(HAVE_STRUCT_UCRED)
111 # if defined(HAVE_GETPEEREID)
115 if (getpeereid(sockfd, &euid, &egid) == 0)
117 if (euid != getuid())
119 kdWarning(900) <<
"socket not owned by me! socket uid = " << euid << endl;
120 close(sockfd); sockfd = -1;
126 # warning "Using sloppy security checks"
133 if (KDE_lstat(sock, &s)!=0)
135 kdWarning(900) <<
"stat failed (" << sock <<
")" << endl;
136 close(sockfd); sockfd = -1;
139 if (s.st_uid != getuid())
141 kdWarning(900) <<
"socket not owned by me! socket uid = " << s.st_uid << endl;
142 close(sockfd); sockfd = -1;
145 if (!S_ISSOCK(s.st_mode))
147 kdWarning(900) <<
"socket is not a socket (" << sock <<
")" << endl;
148 close(sockfd); sockfd = -1;
152 #elif defined(HAVE_GETPEERUCRED)
153 ucred_t *cred =
nullptr;
155 if (getpeerucred(sockfd, &cred) == 0) {
156 uid_t peer_uid = ucred_geteuid(cred);
159 if (peer_uid != getuid()) {
160 kdWarning(900) <<
"socket not owned by me! socket uid = " << peer_uid << endl;
161 close(sockfd); sockfd = -1;
169 socklen_t siz =
sizeof(cred);
172 if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0)
174 if (cred.uid != getuid())
176 kdWarning(900) <<
"socket not owned by me! socket uid = " << cred.uid << endl;
177 close(sockfd); sockfd = -1;
186 TQCString TDEsuClient::escape(
const TQCString &str)
188 TQCString copy = str;
190 while ((n = copy.find(
"\\", n)) != -1)
192 copy.insert(n,
'\\');
196 while ((n = copy.find(
"\"", n)) != -1)
198 copy.insert(n,
'\\');
206 int TDEsuClient::command(
const TQCString &cmd, TQCString *result)
211 if (send(sockfd, cmd, cmd.length(), 0) != (
int) cmd.length())
215 int nbytes = recv(sockfd, buf, 1023, 0);
218 kdWarning(900) << k_lineinfo <<
"no reply from daemon\n";
221 buf[nbytes] =
'\000';
223 TQCString reply = buf;
224 if (reply.left(2) !=
"OK")
228 *result = reply.mid(3, reply.length()-4);
234 TQCString cmd =
"PASS ";
237 cmd += TQCString().setNum(timeout);
242 int TDEsuClient::exec(
const TQCString &prog,
const TQCString &user,
const TQCString &options,
const QCStringList &env)
249 if (!options.isEmpty() || !env.isEmpty())
252 cmd += escape(options);
253 for(QCStringList::ConstIterator it = env.begin();
254 it != env.end(); ++it)
266 TQCString cmd =
"HOST ";
275 cmd.sprintf(
"PRIO %d\n", prio);
282 cmd.sprintf(
"SCHD %d\n", sched);
288 TQCString cmd =
"DEL ";
296 const TQCString &group)
298 TQCString cmd =
"SET ";
301 cmd += escape(value);
303 cmd += escape(group);
305 cmd += TQCString().setNum(timeout);
312 TQCString cmd =
"GET ";
316 command(cmd, &reply);
322 TQCString cmd =
"GETK ";
323 cmd += escape(group);
326 command(cmd, &reply);
328 TQValueList<TQCString> list;
329 if( !reply.isEmpty() )
334 pos = reply.find(
'\007', index );
338 list.append( reply );
340 list.append( reply.mid(index) );
345 list.append( reply.mid(index, pos-index) );
355 TQCString cmd =
"CHKG ";
356 cmd += escape(group);
358 if( command(cmd) == -1 )
365 TQCString cmd =
"DELV ";
373 TQCString cmd =
"DELG ";
374 cmd += escape(group);
381 TQCString cmd =
"DELS ";
382 cmd += escape(special_key);
389 return command(
"PING\n");
395 if (command(
"EXIT\n", &result) != 0)
398 return result.toLong();
403 return command(
"STOP\n");
406 static TQString findDaemon()
408 TQString daemon = locate(
"bin",
"tdesud");
409 if (daemon.isEmpty())
410 daemon = TDEStandardDirs::findExe(
"tdesud");
412 if (daemon.isEmpty())
414 kdWarning(900) << k_lineinfo <<
"daemon not found\n";
421 if (d->daemon.isEmpty())
422 d->daemon = findDaemon();
423 if (d->daemon.isEmpty())
426 KDE_struct_stat sbuf;
427 if (KDE_stat(TQFile::encodeName(d->daemon), &sbuf) < 0)
429 kdWarning(900) << k_lineinfo <<
"stat(): " << perror <<
"\n";
432 return (sbuf.st_mode & S_ISGID);
437 if (d->daemon.isEmpty())
438 d->daemon = findDaemon();
439 if (d->daemon.isEmpty())
443 kdWarning(900) << k_lineinfo <<
"tdesud not setgid!\n";
450 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.