00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "RConfig.h"
00019
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <sys/socket.h>
00025 #include <sys/un.h>
00026 #include <fcntl.h>
00027 #include <sys/stat.h>
00028 #include <errno.h>
00029 #include <sys/types.h>
00030 #include <time.h>
00031 #include <netinet/in.h>
00032 #include <netinet/tcp.h>
00033 #include <arpa/inet.h>
00034 #include <netdb.h>
00035
00036 #if (defined(R__AIX) && !defined(_AIX43)) || \
00037 (defined(R__SUNGCC3) && !defined(__arch64__))
00038 # define USE_SIZE_T
00039 #elif defined(R__GLIBC) || defined(R__FBSD) || \
00040 (defined(R__SUNGCC3) && defined(__arch64__)) || \
00041 defined(R__OBSD) || defined(MAC_OS_X_VERSION_10_4) || \
00042 (defined(R__AIX) && defined(_AIX43))
00043 # define USE_SOCKLEN_T
00044 #endif
00045
00046 #include "rpdp.h"
00047
00048 extern int gDebug;
00049
00050 namespace ROOT {
00051
00052
00053 int SshToolAllocateSocket(unsigned int Uid, unsigned int Gid, char **pipe)
00054 {
00055
00056
00057
00058
00059 if (gDebug > 2)
00060 ErrorInfo("SshToolAllocateSocket: enter: Uid:%d Gid:%d", Uid, Gid);
00061
00062
00063 int sd;
00064 if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00065 ErrorInfo("SshToolAllocateSocket: error opening socket");
00066 return -1;
00067 }
00068
00069 struct sockaddr_un servAddr;
00070 servAddr.sun_family = AF_UNIX;
00071
00072 int nAtt0 = 0;
00073
00074 tryagain:
00075
00076 char fsun[25] = {0};
00077 if (access("/tmp",W_OK) == 0) {
00078 strncpy(fsun, "/tmp/rootdSSH_XXXXXX", 24);
00079 } else {
00080 strncpy(fsun, "rootdSSH_XXXXXX", 24);
00081 }
00082 mode_t oldumask = umask(0700);
00083 int itmp = mkstemp(fsun);
00084 Int_t nAtt = 0;
00085 while (itmp == -1 && nAtt < kMAXRSATRIES) {
00086 nAtt++;
00087 if (gDebug > 0)
00088 ErrorInfo("SshToolAllocateSocket: mkstemp failure (nAtt: %d, errno: %d)",
00089 nAtt,errno);
00090 itmp = mkstemp(fsun);
00091 }
00092 umask(oldumask);
00093 if (itmp == -1) {
00094 ErrorInfo("SshToolAllocateSocket: mkstemp failed %d times - return",
00095 kMAXRSATRIES);
00096 return -1;
00097 } else {
00098 close(itmp);
00099 unlink(fsun);
00100 }
00101 nAtt0++;
00102 if (gDebug > 2)
00103 ErrorInfo("SshToolAllocateSocket: unique pipe name is %s (try: %d)",
00104 fsun, nAtt0);
00105
00106
00107 strncpy(servAddr.sun_path, fsun, 104);
00108
00109
00110 if (bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
00111 if (errno == EADDRINUSE && nAtt0 < kMAXRSATRIES) {
00112 if (gDebug > 2)
00113 ErrorInfo
00114 ("SshToolAllocateSocket: address in use: try again (try: %d)");
00115 goto tryagain;
00116 } else {
00117 ErrorInfo
00118 ("SshToolAllocateSocket: unable to bind to socket %d (errno: %d)",
00119 sd, errno);
00120 return -1;
00121 }
00122 }
00123
00124 if (listen(sd, 5)) {
00125 ErrorInfo
00126 ("SshToolAllocateSocket: can't activate listening (errno: %d)",
00127 errno);
00128 return -1;
00129 }
00130
00131
00132
00133
00134 struct stat sst;
00135
00136
00137 fstat(sd, &sst);
00138 if ((unsigned int)sst.st_uid != Uid || (unsigned int)sst.st_gid != Gid) {
00139 if (fchown(sd, Uid, Gid)) {
00140 if (gDebug > 0) {
00141 ErrorInfo("SshToolAllocateSocket: fchown: could not change socket"
00142 " %d ownership (errno= %d) ",sd, errno);
00143 ErrorInfo("SshToolAllocateSocket: socket (uid,gid) are: %d %d",
00144 sst.st_uid, sst.st_gid);
00145 ErrorInfo("SshToolAllocateSocket: may follow authentication problems");
00146 }
00147 }
00148 }
00149
00150 if (chown(fsun, Uid, Gid) != 0) {
00151 if (gDebug > 0) {
00152 ErrorInfo("SshToolAllocateSocket: chown: could not change path"
00153 " '%s' ownership (errno= %d)",fsun, errno);
00154 ErrorInfo("SshToolAllocateSocket: path (uid,gid) are: %d %d",
00155 sst.st_uid, sst.st_gid);
00156 ErrorInfo("SshToolAllocateSocket: may follow authentication problems");
00157 }
00158 return -1;
00159 }
00160
00161
00162
00163
00164 if (chmod(fsun, 0600)) {
00165 if (gDebug > 0) {
00166 ErrorInfo("SshToolAllocateSocket: chmod: could not change"
00167 " '%s' permission (errno= %d)",fsun, errno);
00168 ErrorInfo("SshToolAllocateSocket: path (uid,gid) are: %d %d",
00169 sst.st_uid, sst.st_gid);
00170 SshToolDiscardSocket(fsun,sd);
00171 return -1;
00172 }
00173 }
00174
00175
00176 *pipe = strdup(fsun);
00177
00178
00179 return sd;
00180 }
00181
00182
00183
00184 void SshToolDiscardSocket(const char *pipe, int sockfd)
00185 {
00186
00187
00188 if (gDebug > 2)
00189 ErrorInfo
00190 ("SshToolDiscardSocket: discarding socket: pipe: %s, fd: %d",
00191 pipe, sockfd);
00192
00193
00194 if (unlink(pipe) == -1) {
00195 if (GetErrno() != ENOENT) {
00196 ErrorInfo("SshToolDiscardSocket: unable to unlink %s"
00197 "(errno: %d, ENOENT= %d)", pipe, GetErrno(), ENOENT);
00198 }
00199 }
00200
00201 close(sockfd);
00202 }
00203
00204
00205 int SshToolNotifyFailure(const char *Pipe)
00206 {
00207
00208
00209 if (gDebug > 2)
00210 ErrorInfo("SshToolNotifyFailure: notifying failure to pipe %s\n",
00211 Pipe);
00212
00213
00214 int sd;
00215 struct sockaddr_un servAddr;
00216 servAddr.sun_family = AF_UNIX;
00217 memcpy((void *) servAddr.sun_path, (void *) Pipe, 108);
00218 servAddr.sun_path[107] = '\0';
00219 if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00220 ErrorInfo("SshToolNotifyFailure: cannot open socket: exiting ");
00221 return 1;
00222 }
00223
00224 int rc;
00225 if ((rc =
00226 connect(sd, (struct sockaddr *) &servAddr,
00227 sizeof(servAddr))) < 0) {
00228 ErrorInfo("SshToolNotifyFailure: cannot connect socket: exiting ");
00229 return 1;
00230 }
00231
00232 const char *okbuf = "KO";
00233 rc = send(sd, okbuf, strlen(okbuf), 0);
00234 if (rc != 2) {
00235 ErrorInfo
00236 ("SshToolNotifyFailure: sending might have been unsuccessful (bytes send: %d)",
00237 rc);
00238 }
00239
00240 return 0;
00241 }
00242
00243
00244 int SshToolGetAuth(int UnixFd, const char *User)
00245 {
00246 int auth = 0;
00247
00248 if (gDebug > 2)
00249 ErrorInfo("SshToolGetAuth: accepting connections on socket %d"
00250 " for user %s",UnixFd,User);
00251
00252
00253 struct sockaddr sunAddr;
00254 #if defined(USE_SIZE_T)
00255 size_t sunAddrLen = sizeof(sunAddr);
00256 #elif defined(USE_SOCKLEN_T)
00257 socklen_t sunAddrLen = sizeof(sunAddr);
00258 #else
00259 int sunAddrLen = sizeof(sunAddr);
00260 #endif
00261 int newUnixFd =
00262 accept(UnixFd, (struct sockaddr *) &sunAddr, &sunAddrLen);
00263 if (newUnixFd < 0) {
00264 ErrorInfo
00265 ("SshToolGetAuth: problems while accepting new connection (errno: %d)", (int) errno);
00266 return auth;
00267 }
00268
00269 int lenr[1], nr, len = 0;
00270 if ((nr = NetRecvRaw(newUnixFd, lenr, sizeof(lenr))) < 0) {
00271 ErrorInfo
00272 ("SshToolGetAuth: incorrect recv from ssh2rpd: bytes:%d, buffer:%d",
00273 nr, lenr[0]);
00274 return auth;
00275 }
00276
00277
00278 len = ntohl(lenr[0]) + 1;
00279 char *sshAuth = 0;
00280 if (len > 0) {
00281 sshAuth = new char[len];
00282 if (sshAuth) {
00283 if ((nr = NetRecvRaw(newUnixFd, sshAuth, len)) != len) {
00284 ErrorInfo
00285 ("SshToolGetAuth: incorrect recv from ssh2rpd: nr:%d, buf:%s",
00286 nr, sshAuth);
00287 } else
00288 sshAuth[len-1] = 0;
00289 if (gDebug > 2)
00290 ErrorInfo("SshToolGetAuth: got: %s",sshAuth);
00291
00292
00293 if (strncmp(sshAuth, "OK", 2) != 0) {
00294 ErrorInfo("SshToolGetAuth: user did not authenticate to sshd: %s (%d)",
00295 sshAuth, strncmp(sshAuth, "OK", 2));
00296 } else {
00297 if (len > 3) {
00298 if (strcmp((const char *)(sshAuth+3), User) != 0) {
00299 ErrorInfo("SshToolGetAuth: authenticated user not the same"
00300 " as requested login username: %s (%s)",
00301 sshAuth+3, User);
00302 auth = -1;
00303 } else {
00304 auth = 1;
00305 }
00306 } else
00307 auth = -1;
00308 }
00309 delete[] sshAuth;
00310 }
00311 }
00312
00313
00314 close(newUnixFd);
00315
00316 return auth;
00317 }
00318
00319 }