00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "RConfigure.h"
00021 #include "RConfig.h"
00022
00023 #include <ctype.h>
00024 #include <fcntl.h>
00025 #include <pwd.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <string>
00029 #include <stdlib.h>
00030 #include <unistd.h>
00031 #include <time.h>
00032 #include <sys/time.h>
00033 #include <sys/stat.h>
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <errno.h>
00037 #include <netdb.h>
00038 #include <math.h>
00039 #include "snprintf.h"
00040
00041 #if defined(__CYGWIN__) && defined(__GNUC__)
00042 # define cygwingcc
00043 #endif
00044
00045 #if defined(linux) || defined(__sun) || defined(__sgi) || \
00046 defined(_AIX) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
00047 defined(__APPLE__) || defined(__MACH__) || defined(cygwingcc)
00048 #include <grp.h>
00049 #include <sys/types.h>
00050 #include <signal.h>
00051 #endif
00052
00053 #ifdef _AIX
00054 extern "C" int ruserok(char *, int, char *, char *);
00055 #endif
00056
00057 #if defined(__alpha) && !defined(linux)
00058 # ifdef _XOPEN_SOURCE
00059 # if _XOPEN_SOURCE+0 > 0
00060 # define R__TRUE64
00061 # endif
00062 # endif
00063 #include <sys/mount.h>
00064 #ifndef R__TRUE64
00065 extern "C" int fstatfs(int file_descriptor, struct statfs *buffer);
00066 extern "C" int ruserok(const char *, int, const char *, const char *);
00067 #endif
00068 #elif defined(__APPLE__)
00069 #include <sys/mount.h>
00070 extern "C" int fstatfs(int file_descriptor, struct statfs *buffer);
00071 #elif defined(linux) || defined(__hpux)
00072 #include <sys/vfs.h>
00073 #elif defined(__FreeBSD__) || defined(__OpenBSD__)
00074 #include <sys/param.h>
00075 #include <sys/mount.h>
00076 #else
00077 #include <sys/statfs.h>
00078 #endif
00079
00080 #if defined(linux)
00081 # include <features.h>
00082 # if __GNU_LIBRARY__ == 6
00083 # ifndef R__GLIBC
00084 # define R__GLIBC
00085 # endif
00086 # endif
00087 #endif
00088 #if defined(cygwingcc) || (defined(__MACH__) && !defined(__APPLE__))
00089 # define R__GLIBC
00090 #endif
00091
00092 #if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || defined(__OpenBSD__) || \
00093 (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
00094 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
00095 #include <sys/file.h>
00096 #define lockf(fd, op, sz) flock((fd), (op))
00097 #ifndef F_LOCK
00098 #define F_LOCK (LOCK_EX | LOCK_NB)
00099 #endif
00100 #ifndef F_ULOCK
00101 #define F_ULOCK LOCK_UN
00102 #endif
00103 #endif
00104
00105 #if defined(cygwingcc)
00106 #define F_LOCK F_WRLCK
00107 #define F_ULOCK F_UNLCK
00108 int ruserok(const char *, int, const char *, const char *) {
00109 return 0;
00110 }
00111 static int fcntl_lockf(int fd, int op, off_t off)
00112 {
00113 flock fl;
00114 fl.l_whence = SEEK_SET;
00115 fl.l_start = off;
00116 fl.l_len = 0;
00117 fl.l_pid = getpid();
00118 fl.l_type = op;
00119 return fcntl(fd, F_SETLK, &fl);
00120 }
00121 #define lockf fcntl_lockf
00122 #endif
00123
00124 #if defined(__sun) || defined(R__GLIBC)
00125 #include <crypt.h>
00126 #endif
00127
00128 #if defined(__osf__) || defined(__sgi) || defined(R__MACOSX)
00129 extern "C" char *crypt(const char *, const char *);
00130 #endif
00131
00132 #ifdef R__WIN32
00133 #define R__NOCRYPT
00134 #endif
00135
00136 #ifdef R__NOCRYPT
00137 static std::string gRndmSalt = std::string("ABCDEFGH");
00138 #endif
00139
00140 #if defined(__sun)
00141 #ifndef R__SHADOWPW
00142 #define R__SHADOWPW
00143 #endif
00144 #endif
00145
00146 #ifdef R__SHADOWPW
00147 #include <shadow.h>
00148 #endif
00149
00150 #ifdef R__AFS
00151 #include "AFSAuth.h"
00152 #endif
00153
00154 #ifdef R__SRP
00155 extern "C" {
00156 #include <t_pwd.h>
00157 #include <t_server.h>
00158 }
00159 #endif
00160
00161 #ifdef R__KRB5
00162 #include "Krb5Auth.h"
00163 #include <string>
00164 extern krb5_deltat krb5_clockskew;
00165 #endif
00166
00167 #ifdef R__SSL
00168
00169 #include <openssl/bio.h>
00170 #include <openssl/blowfish.h>
00171 #include <openssl/err.h>
00172 #include <openssl/pem.h>
00173 #include <openssl/rand.h>
00174 #include <openssl/rsa.h>
00175 #include <openssl/ssl.h>
00176 #endif
00177
00178 #include "rpdp.h"
00179 #include "rsadef.h"
00180 #include "rsalib.h"
00181
00182
00183 static ERootdErrors gUsrPwdErr[4][4] = {
00184 {kErrNoPasswd, kErrNoPassHEquNoFiles, kErrNoPassHEquBadFiles, kErrNoPassHEquFailed},
00185 {kErrBadPasswd, kErrBadPassHEquNoFiles, kErrBadPassHEquBadFiles, kErrBadPassHEquFailed},
00186 {kErrBadRtag, kErrBadRtagHEquNoFiles, kErrBadRtagHEquBadFiles, kErrBadRtagHEquFailed},
00187 {kErrBadPwdFile, kErrBadPwdFileHEquNoFiles, kErrBadPwdFileHEquBadFiles,
00188 kErrBadPwdFileHEquFailed}};
00189
00190
00191
00192 #if defined(__alpha) && !defined(linux) && !defined(__FreeBSD__) && \
00193 !defined(__OpenBSD__)
00194 extern "C" int initgroups(const char *name, int basegid);
00195 #endif
00196
00197 #if defined(__sgi) && !defined(__GNUG__) && (SGI_REL<62)
00198 extern "C" {
00199 int seteuid(int euid);
00200 int setegid(int egid);
00201 }
00202 #endif
00203
00204 #if defined(_AIX)
00205 extern "C" {
00206 int seteuid(uid_t euid);
00207 int setegid(gid_t egid);
00208 }
00209 #endif
00210
00211 #if !defined(__hpux) && !defined(linux) && !defined(__FreeBSD__) && \
00212 !defined(__OpenBSD__) || defined(cygwingcc)
00213 static int setresgid(gid_t r, gid_t e, gid_t)
00214 {
00215 if (setgid(r) == -1)
00216 return -1;
00217 return setegid(e);
00218 }
00219
00220 static int setresuid(uid_t r, uid_t e, uid_t)
00221 {
00222 if (setuid(r) == -1)
00223 return -1;
00224 return seteuid(e);
00225 }
00226 #else
00227 #if defined(linux) && !defined(R__HAS_SETRESUID)
00228 extern "C" {
00229 int setresgid(gid_t r, gid_t e, gid_t s);
00230 int setresuid(uid_t r, uid_t e, uid_t s);
00231 }
00232 #endif
00233 #endif
00234
00235 #if defined(__sun)
00236 #if defined(R__SUNGCC3)
00237 extern "C" int gethostname(char *, unsigned int);
00238 #else
00239 extern "C" int gethostname(char *, int);
00240 #endif
00241 #endif
00242
00243 extern int gDebug;
00244
00245 namespace ROOT {
00246
00247
00248
00249 ErrorHandler_t gErrSys = 0;
00250 ErrorHandler_t gErrFatal = 0;
00251 ErrorHandler_t gErr = 0;
00252 bool gSysLog = 0;
00253 std::string gServName[3] = { "sockd", "rootd", "proofd" };
00254
00255
00256
00257 static const int gAUTH_CLR_MSK = 0x1;
00258 static const int gAUTH_SRP_MSK = 0x2;
00259 static const int gAUTH_KRB_MSK = 0x4;
00260 static const int gAUTH_GLB_MSK = 0x8;
00261 static const int gAUTH_SSH_MSK = 0x10;
00262 static const int gMAXTABSIZE = 50000000;
00263
00264 static const std::string gAuthMeth[kMAXSEC] = { "UsrPwd", "SRP", "Krb5",
00265 "Globus", "SSH", "UidGid" };
00266 static const std::string gAuthTab = "/rpdauthtab";
00267 static const std::string gDaemonRc = ".rootdaemonrc";
00268 static const std::string gRootdPass = ".rootdpass";
00269 static const std::string gSRootdPass = "/.srootdpass";
00270 static const std::string gKeyRoot = "/rpk.";
00271
00272
00273
00274 static std::string gTmpDir = "/tmp";
00275
00276
00277
00278 static int gAuthProtocol = -1;
00279 static char gBufOld[kMAXRECVBUF] = {0};
00280 static bool gCheckHostsEquiv = 1;
00281 static int gClientOld = 0;
00282 static int gClientProtocol = -1;
00283 static int gCryptRequired = -1;
00284 static std::string gCryptToken;
00285 static int gAllowMeth[kMAXSEC];
00286 static std::string gAltSRPPass;
00287 static int gAnon = 0;
00288 static int gExistingAuth = 0;
00289 static int gAuthListSent = 0;
00290 static int gHaveMeth[kMAXSEC];
00291 static EMessageTypes gKindOld;
00292 static int gMethInit = 0;
00293 static int gNumAllow = -1;
00294 static int gNumLeft = -1;
00295 static int gOffSet = -1;
00296 static std::string gOpenHost = "????";
00297 static int gParentId = -1;
00298 static char gPasswd[kMAXUSERLEN] = { 0 };
00299 static char gPubKey[kMAXPATHLEN] = { 0 };
00300 static int gPubKeyLen = 0;
00301 static int gRandInit = 0;
00302 static int gRemPid = -1;
00303 static bool gRequireAuth = 1;
00304 static int gReUseAllow = 0x1F;
00305 static int gReUseRequired = -1;
00306 static int gDoLogin = 0;
00307 static std::string gRpdAuthTab = std::string(gTmpDir).append(gAuthTab);
00308 static std::string gRpdKeyRoot = std::string(gTmpDir).append(gKeyRoot);
00309 static rsa_NUMBER gRSA_d;
00310 static rsa_NUMBER gRSA_n;
00311 static int gRSAInit = 0;
00312 static int gRSAKey = 0;
00313 static rsa_KEY gRSAPriKey;
00314 static rsa_KEY_export gRSAPubExport[2] = {{0,0},{0,0}};
00315 static rsa_KEY gRSAPubKey;
00316 #ifdef R__SSL
00317 static BF_KEY gBFKey;
00318 static RSA *gRSASSLKey = 0;
00319 #endif
00320 static int gSaltRequired = -1;
00321 static int gSec = -1;
00322 static int gServerProtocol = -1;
00323 static EService gService = kROOTD;
00324 static int gSshdPort = 22;
00325 static int gTriedMeth[kMAXSEC];
00326 static char gUser[64] = { 0 };
00327 static char *gUserAllow[kMAXSEC] = { 0 };
00328 static unsigned int gUserAlwLen[kMAXSEC] = { 0 };
00329 static unsigned int gUserIgnLen[kMAXSEC] = { 0 };
00330 static char *gUserIgnore[kMAXSEC] = { 0 };
00331
00332
00333
00334 #ifdef R__KRB5
00335 static krb5_context gKcontext;
00336 static krb5_keytab gKeytab = 0;
00337 static std::string gKeytabFile = "";
00338 #endif
00339
00340
00341
00342 #ifdef R__GLBS
00343 static int gShmIdCred = -1;
00344 static gss_cred_id_t gGlbCredHandle = GSS_C_NO_CREDENTIAL;
00345 static bool gHaveGlobus = 1;
00346 static std::string gGlobusSubjName;
00347 #endif
00348
00349
00350 static int rpd_rand()
00351 {
00352
00353
00354 #ifndef WIN32
00355 int frnd = open("/dev/urandom", O_RDONLY);
00356 if (frnd < 0) frnd = open("/dev/random", O_RDONLY);
00357 int r;
00358 if (frnd >= 0) {
00359 ssize_t rs = read(frnd, (void *) &r, sizeof(int));
00360 close(frnd);
00361 if (r < 0) r = -r;
00362 if (rs == sizeof(int)) return r;
00363 }
00364 ErrorInfo("+++ERROR+++ : rpd_rand: neither /dev/urandom nor /dev/random are available or readable!");
00365 struct timeval tv;
00366 if (gettimeofday(&tv,0) == 0) {
00367 int t1, t2;
00368 memcpy((void *)&t1, (void *)&tv.tv_sec, sizeof(int));
00369 memcpy((void *)&t2, (void *)&tv.tv_usec, sizeof(int));
00370 r = t1 + t2;
00371 if (r < 0) r = -r;
00372 return r;
00373 }
00374 return -1;
00375 #else
00376
00377 return rand();
00378 #endif
00379 }
00380
00381
00382 static int reads(int fd, char *buf, int len)
00383 {
00384
00385
00386
00387
00388
00389
00390
00391
00392 int k = 0;
00393 int nread = -1;
00394 int nr = read(fd,buf,1);
00395 while (nr > 0 && buf[k] != '\n' && k < (len-1)) {
00396 k++;
00397 nr = read(fd,buf+k,1);
00398 }
00399 if (k >= len-1) {
00400 buf[k] = 0;
00401 nread = len-1;
00402 } else if (buf[k] == '\n'){
00403 if (k <= len-2) {
00404 buf[k+1] = 0;
00405 nread = k+1;
00406 } else {
00407 buf[k] = 0;
00408 nread = k;
00409 }
00410 } else if (nr == 0) {
00411 if (k > 0) {
00412 buf[k-1] = 0;
00413 nread = k-1;
00414 } else {
00415 buf[0] = 0;
00416 nread = 0;
00417 }
00418 } else if (nr < 0) {
00419 if (k > 0) {
00420 buf[k] = 0;
00421 nread = -(k-1);
00422 } else {
00423 buf[0] = 0;
00424 nread = -1;
00425 }
00426 }
00427
00428 if (nread >= 0) buf[nread] = 0;
00429
00430 return nread;
00431 }
00432
00433
00434 static int rpdstrncasecmp(const char *str1, const char *str2, int n)
00435 {
00436
00437
00438 while (n > 0) {
00439 int c1 = *str1;
00440 int c2 = *str2;
00441
00442 if (isupper(c1))
00443 c1 = tolower(c1);
00444
00445 if (isupper(c2))
00446 c2 = tolower(c2);
00447
00448 if (c1 != c2)
00449 return c1 - c2;
00450
00451 str1++;
00452 str2++;
00453 n--;
00454 }
00455 return 0;
00456 }
00457
00458
00459 static int rpdstrcasecmp(const char *str1, const char *str2)
00460 {
00461
00462
00463 return rpdstrncasecmp(str1, str2, strlen(str2) + 1);
00464 }
00465
00466
00467 static volatile void *rpdmemset(volatile void *dst, int c, int len)
00468 {
00469
00470
00471
00472 volatile char *buf;
00473
00474 for (buf = (volatile char *)dst; len; (buf[--len] = c)) { }
00475 return dst;
00476 }
00477
00478 #ifdef R__NOCRYPT
00479
00480 char *rpdcrypt(const char *pw, const char *sa)
00481 {
00482
00483
00484
00485
00486
00487 static char buf[129];
00488 char tbuf[64];
00489 int np = (strlen(pw) < 64) ? strlen(pw) : 64;
00490 int ns = strlen(sa);
00491 char c;
00492
00493 int i = 0;
00494 for (i=0; i<np; i++) {
00495
00496
00497 int ks = i%ns;
00498 tbuf[i] = pw[i]^sa[ks];
00499
00500 int j = 0xF & tbuf[i];
00501 if (j < 10)
00502 c = 48 + j;
00503 else
00504 c = 55 + j;
00505 int k = 2*i;
00506 buf[k] = c;
00507
00508 j = (0xF0 & tbuf[i]) >> 4;
00509 if (j < 10)
00510 c = 48 + j;
00511 else
00512 c = 55 + j;
00513 k = 2*i + 1;
00514 buf[k] = c;
00515 }
00516
00517 buf[np*2] = 0;
00518
00519 return buf;
00520 }
00521 #endif
00522
00523
00524 void RpdSetSysLogFlag(int syslog)
00525 {
00526
00527
00528
00529
00530
00531 gSysLog = syslog;
00532 if (gDebug > 2)
00533 ErrorInfo("RpdSetSysLogFlag: gSysLog set to %d", gSysLog);
00534 }
00535
00536
00537 void RpdSetMethInitFlag(int methinit)
00538 {
00539
00540
00541
00542
00543
00544 gMethInit = methinit;
00545 if (gDebug > 2)
00546 ErrorInfo("RpdSetMethInitFlag: gMethInit set to %d", gMethInit);
00547 }
00548
00549 const char *RpdGetKeyRoot()
00550 {
00551
00552
00553 return (const char *)gRpdKeyRoot.c_str();
00554 }
00555
00556
00557 int RpdGetClientProtocol()
00558 {
00559
00560
00561 return gClientProtocol;
00562 }
00563
00564
00565 int RpdGetAuthProtocol()
00566 {
00567
00568
00569 return gAuthProtocol;
00570 }
00571
00572
00573 int RpdGetOffSet()
00574 {
00575
00576
00577 return gOffSet;
00578 }
00579
00580 #ifdef R__KRB5
00581
00582 void RpdSetKeytabFile(const char *keytabfile)
00583 {
00584
00585 gKeytabFile = std::string(keytabfile);
00586 if (gDebug > 2)
00587 ErrorInfo("RpdSetKeytabFile: using keytab file %s", gKeytabFile.c_str());
00588 }
00589
00590
00591 void RpdFreeKrb5Vars(krb5_context context, krb5_principal principal,
00592 krb5_ticket *ticket, krb5_auth_context auth_context,
00593 krb5_creds **creds)
00594 {
00595
00596
00597 if (context) {
00598
00599 if (creds)
00600 krb5_free_tgt_creds(context,creds);
00601
00602
00603 if (auth_context)
00604 krb5_auth_con_free(context, auth_context);
00605
00606
00607 if (ticket)
00608 krb5_free_ticket(context,ticket);
00609
00610
00611 if (principal)
00612 krb5_free_principal(context, principal);
00613
00614
00615 krb5_free_context(context);
00616 }
00617 }
00618
00619 #endif
00620
00621
00622 int RpdGetAuthMethod(int kind)
00623 {
00624 int method = -1;
00625
00626 if (kind == kROOTD_USER)
00627 method = 0;
00628 if (kind == kROOTD_SRPUSER)
00629 method = 1;
00630 if (kind == kROOTD_KRB5)
00631 method = 2;
00632 if (kind == kROOTD_GLOBUS)
00633 method = 3;
00634 if (kind == kROOTD_SSH)
00635 method = 4;
00636 if (kind == kROOTD_RFIO)
00637 method = 5;
00638
00639 return method;
00640 }
00641
00642
00643 int RpdDeleteKeyFile(int ofs)
00644 {
00645
00646
00647
00648 int retval = 0;
00649
00650 std::string pukfile = gRpdKeyRoot;
00651 pukfile.append(ItoA(ofs));
00652
00653
00654 if (gDebug > 2) {
00655 ErrorInfo("RpdDeleteKeyFile: proc uid:%d gid:%d",
00656 getuid(),getgid());
00657 }
00658
00659
00660 if (unlink(pukfile.c_str()) == -1) {
00661 if (gDebug > 0 && GetErrno() != ENOENT) {
00662 ErrorInfo("RpdDeleteKeyFile: problems unlinking pub"
00663 " key file '%s' (errno: %d)",
00664 pukfile.c_str(),GetErrno());
00665 }
00666 retval = 1;
00667 }
00668 return retval;
00669 }
00670
00671
00672 int RpdUpdateAuthTab(int opt, const char *line, char **token, int ilck)
00673 {
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 int retval = -1;
00686 int itab = 0;
00687 char fbuf[kMAXPATHLEN];
00688
00689 if (gDebug > 2)
00690 ErrorInfo("RpdUpdateAuthTab: analyzing: opt: %d, line: %s, ilck: %d",
00691 opt, line, ilck);
00692
00693 if (ilck <= 0) {
00694
00695
00696 itab = open(gRpdAuthTab.c_str(), O_RDWR);
00697 if (itab == -1) {
00698 if (opt == 1 && GetErrno() == ENOENT) {
00699
00700 itab = open(gRpdAuthTab.c_str(), O_RDWR | O_CREAT, 0600);
00701 if (itab == -1) {
00702 ErrorInfo("RpdUpdateAuthTab: opt=%d: error opening %s"
00703 "(errno: %d)",
00704 opt, gRpdAuthTab.c_str(), GetErrno());
00705 return retval;
00706 }
00707 } else {
00708 ErrorInfo("RpdUpdateAuthTab: opt=%d: error opening %s"
00709 " (errno: %d)",
00710 opt, gRpdAuthTab.c_str(), GetErrno());
00711 return retval;
00712 }
00713 }
00714
00715
00716 if (lockf(itab, F_LOCK, (off_t) 1) == -1) {
00717 ErrorInfo("RpdUpdateAuthTab: opt=%d: error locking %s"
00718 " (errno: %d)", opt, gRpdAuthTab.c_str(), GetErrno());
00719 close(itab);
00720 return retval;
00721 }
00722 if (gDebug > 0)
00723 ErrorInfo("RpdUpdateAuthTab: opt= %d - file LOCKED", opt);
00724 } else {
00725 itab = ilck;
00726 }
00727
00728
00729 int fsize = 0;
00730 if ((fsize = lseek(itab, 0, SEEK_END)) == -1) {
00731 ErrorInfo("RpdUpdateAuthTab: opt=%d: lseek error (errno: %d)",
00732 opt, GetErrno());
00733 goto goingout;
00734 }
00735
00736
00737 if (lseek(itab, 0, SEEK_SET) == -1) {
00738 ErrorInfo("RpdUpdateAuthTab: opt=%d: lseek error (errno: %d)",
00739 opt, GetErrno());
00740 goto goingout;
00741 }
00742
00743 if (opt == -1) {
00744
00745
00746
00747
00748
00749 std::string bak = std::string(gRpdAuthTab).append(".bak");
00750 int ibak = open(bak.c_str(), O_RDWR | O_CREAT, 0600);
00751 if (ibak == -1) {
00752 ErrorInfo("RpdUpdateAuthTab: opt=%d: error opening/creating %s"
00753 " (errno: %d)", opt, bak.c_str(), GetErrno());
00754 goto goingout;
00755 }
00756
00757
00758 if (ftruncate(ibak, 0) == -1)
00759 ErrorInfo("RpdUpdateAuthTab: opt=%d: ftruncate error (%s)"
00760 " (errno: %d)", opt, bak.c_str(), GetErrno());
00761
00762
00763 char buf[kMAXPATHLEN];
00764 int ofs = 0, nr = 0;
00765 while ((nr = reads(itab, buf, sizeof(buf)))) {
00766 int slen = strlen(buf);
00767
00768
00769 if (buf[slen-1] != '\n') {
00770 if (slen >= kMAXPATHLEN -1)
00771 buf[slen-1] = '\n';
00772 else {
00773 buf[slen] = '\n';
00774 buf[slen+1] = '\0';
00775 }
00776 }
00777 if (slen) {
00778 while (write(ibak, buf, slen) < 0 && GetErrno() == EINTR)
00779 ResetErrno();
00780 }
00781
00782
00783 RpdDeleteKeyFile(ofs);
00784
00785 ofs += slen;
00786 }
00787 close(ibak);
00788
00789
00790 if (ftruncate(itab, 0) == -1)
00791 ErrorInfo("RpdUpdateAuthTab: opt=%d: ftruncate error (%s)"
00792 " (errno: %d)", opt, gRpdAuthTab.c_str(), GetErrno());
00793 retval = 0;
00794
00795 } else if (opt == 0) {
00796
00797
00798
00799
00800
00801 int pr = 0, pw = 0;
00802 int lsec, act, oldofs = 0, bytesread = 0;
00803 char ln[kMAXPATHLEN], dumm[kMAXPATHLEN];
00804 bool fwr = 0;
00805
00806 while ((bytesread = reads(itab, ln, sizeof(ln)))) {
00807
00808 bool ok = 1;
00809
00810 if ((pr = lseek(itab,0,SEEK_CUR)) < 0) {
00811 ErrorInfo("RpdUpdateAuthTab: opt=%d: problems lseeking file %s"
00812 " (errno: %d)", opt, gRpdAuthTab.c_str(), errno);
00813 fwr = 1;
00814 ok = 0;
00815 }
00816
00817
00818 int slen = bytesread;
00819 if (ok && slen < 1) {
00820 ErrorInfo("RpdUpdateAuthTab: opt=%d: file %s seems corrupted"
00821 " (slen: %d)", opt, gRpdAuthTab.c_str(), slen);
00822 fwr = 1;
00823 ok = 0;
00824 }
00825 if (ok) {
00826
00827 int ns = sscanf(ln, "%d %d %4095s", &lsec, &act, dumm);
00828 if (ns < 3 ) {
00829 ErrorInfo("RpdUpdateAuthTab: opt=%d: file %s seems corrupted"
00830 " (ns: %d)", opt, gRpdAuthTab.c_str(), ns);
00831 fwr = 1;
00832 ok = 0;
00833 }
00834 }
00835
00836 if (ok && act > 0) {
00837 if (fwr) {
00838
00839 int nr = 0;
00840 if ((nr = RpdRenameKeyFile(oldofs,pw)) == 0) {
00841
00842 lseek(itab, pw, SEEK_SET);
00843
00844 if (ln[slen-1] != '\n') {
00845 if (slen >= kMAXPATHLEN -1)
00846 ln[slen-1] = '\n';
00847 else {
00848 ln[slen] = '\n';
00849 ln[slen+1] = '\0';
00850 }
00851 }
00852 while (write(itab, ln, strlen(ln)) < 0
00853 && GetErrno() == EINTR)
00854 ResetErrno();
00855 pw += strlen(ln);
00856 } else
00857 RpdDeleteKeyFile(oldofs);
00858 lseek(itab, pr, SEEK_SET);
00859 } else
00860 pw += strlen(ln);
00861 } else {
00862 fwr = 1;
00863 }
00864
00865 oldofs = pr;
00866 }
00867
00868
00869 if (ftruncate(itab, pw) == -1)
00870 ErrorInfo("RpdUpdateAuthTab: opt=%d: ftruncate error (errno: %d)",
00871 opt, GetErrno());
00872
00873
00874 retval = pw;
00875
00876 } else if (opt == 1) {
00877
00878
00879
00880
00881
00882
00883 if ((int)(fsize+strlen(line)) > gMAXTABSIZE) {
00884
00885
00886 fsize = RpdUpdateAuthTab(0,(const char *)0,0,itab);
00887
00888
00889 if ((int)(fsize+strlen(line)) > gMAXTABSIZE)
00890 fsize = RpdUpdateAuthTab(-1,(const char *)0,0,itab);
00891 }
00892
00893 retval = lseek(itab, 0, SEEK_END);
00894
00895
00896
00897
00898 int ntry = 10;
00899 int rs = 0;
00900 while ((rs = RpdSavePubKey(gPubKey, retval, gUser)) == 2 && ntry--) {
00901
00902
00903
00904 char ltmp[256];
00905 SPrintf(ltmp, 256,
00906 "0 0 %d %d %s error: pubkey file in use: shift offset\n",
00907 gRSAKey, gRemPid, gOpenHost.c_str());
00908
00909
00910 while (write(itab, ltmp, strlen(ltmp)) < 0 && GetErrno() == EINTR)
00911 ResetErrno();
00912
00913
00914 retval = lseek(itab, 0, SEEK_END);
00915 }
00916
00917 if (rs > 0) {
00918
00919 retval = -1;
00920 if (gDebug > 0)
00921 ErrorInfo("RpdUpdateAuthTab: pub key could not be saved (%d)",rs);
00922 } else {
00923
00924 *token = RpdGetRandString(3, 8);
00925 #ifndef R__NOCRYPT
00926 char *cryptToken = crypt(*token, *token);
00927 #else
00928 char *cryptToken = rpdcrypt(*token,gRndmSalt.c_str());
00929 #endif
00930 SPrintf(fbuf, kMAXPATHLEN, "%s %s\n", line, cryptToken);
00931 if (gDebug > 2)
00932 ErrorInfo("RpdUpdateAuthTab: token: '%s'", cryptToken);
00933
00934 gCryptToken = std::string(cryptToken);
00935
00936
00937 while (write(itab, fbuf, strlen(fbuf)) < 0 && GetErrno() == EINTR)
00938 ResetErrno();
00939 }
00940
00941 } else {
00942
00943
00944
00945 ErrorInfo("RpdUpdateAuthTab: unrecognized option (opt= %d)", opt);
00946 }
00947
00948 goingout:
00949 if (ilck == 0) {
00950
00951 lseek(itab, 0, SEEK_SET);
00952 if (lockf(itab, F_ULOCK, (off_t) 1) == -1) {
00953 ErrorInfo("RpdUpdateAuthTab: error unlocking %s",
00954 gRpdAuthTab.c_str());
00955 }
00956
00957
00958 close(itab);
00959 }
00960
00961 return retval;
00962 }
00963
00964
00965 int RpdCleanupAuthTab(const char *crypttoken)
00966 {
00967
00968
00969
00970
00971
00972
00973
00974 int retval = -4;
00975
00976 if (gDebug > 2)
00977 ErrorInfo("RpdCleanupAuthTab: Crypt-token: '%s'",crypttoken);
00978
00979
00980 int itab = -1;
00981 if ((itab = open(gRpdAuthTab.c_str(), O_RDWR)) == -1) {
00982 if (GetErrno() == ENOENT) {
00983 if (gDebug > 0)
00984 ErrorInfo("RpdCleanupAuthTab: file %s does not exist",
00985 gRpdAuthTab.c_str());
00986 return -3;
00987 } else {
00988 ErrorInfo("RpdCleanupAuthTab: error opening %s (errno: %d)",
00989 gRpdAuthTab.c_str(), GetErrno());
00990 return -1;
00991 }
00992 }
00993
00994
00995 if (lockf(itab, F_LOCK, (off_t) 1) == -1) {
00996 ErrorInfo("RpdCleanupAuthTab: error locking %s (errno: %d)",
00997 gRpdAuthTab.c_str(), GetErrno());
00998 close(itab);
00999 return -2;
01000 }
01001 if (gDebug > 0)
01002 ErrorInfo("RpdCleanupAuthTab: file LOCKED (ctkn: '%s')",crypttoken);
01003
01004
01005
01006 int pr = 0, pw = 0;
01007 int nw, lsec, act, remid, pkey;
01008 char line[kMAXPATHLEN];
01009
01010
01011 if ((pr = lseek(itab, 0, SEEK_SET)) < 0) {
01012 ErrorInfo("RpdCleanupAuthTab: error lseeking %s (errno: %d)",
01013 gRpdAuthTab.c_str(), GetErrno());
01014 close(itab);
01015 return -2;
01016 }
01017 pw = pr;
01018 while (reads(itab,line, sizeof(line))) {
01019
01020 pr += strlen(line);
01021 if (gDebug > 2)
01022 ErrorInfo("RpdCleanupAuthTab: pr:%d pw:%d (line:%s) (pId:%d)",
01023 pr, pw, line, gParentId);
01024
01025 char dum1[kMAXPATHLEN] = {0}, host[kMAXUSERLEN] = {0}, user[kMAXUSERLEN] = {0},
01026 ctkn[30] = {0}, dum2[30] = {0};
01027 nw = sscanf(line, "%d %d %d %d %127s %127s %29s %4095s %29s",
01028 &lsec, &act, &pkey, &remid, host, user, ctkn, dum1, dum2);
01029
01030 int deactivate = 0;
01031
01032 if (act > 0) {
01033
01034 if (lsec == 3 && nw == 9) {
01035 if (!strncmp(dum2,crypttoken,strlen(crypttoken)))
01036 deactivate = 1;
01037 } else if (nw == 7) {
01038 if (!strncmp(ctkn,crypttoken,strlen(crypttoken)))
01039 deactivate = 1;
01040 }
01041
01042
01043 if (deactivate) {
01044
01045 retval = 0;
01046
01047
01048 RpdDeleteKeyFile(pw);
01049
01050 #ifdef R__GLBS
01051 if (lsec == 3) {
01052 int shmid = atoi(ctkn);
01053 struct shmid_ds shm_ds;
01054 if (shmctl(shmid, IPC_RMID, &shm_ds) == -1) {
01055 if (GetErrno() != EIDRM) {
01056 ErrorInfo("RpdCleanupAuthTab: unable to mark shared"
01057 " memory segment %d (buf:%s)", shmid, ctkn);
01058 ErrorInfo("RpdCleanupAuthTab: for destruction"
01059 " (errno: %d)", GetErrno());
01060 retval++;
01061 }
01062 }
01063 }
01064 #endif
01065
01066 int slen = (int)strlen(line);
01067 int ka = 0;
01068 while (ka < slen && line[ka] == 32)
01069 ka++;
01070
01071 while (ka < slen && line[ka] != 32)
01072 ka++;
01073
01074 while (ka < slen && line[ka] == 32)
01075 ka++;
01076
01077 line[ka] = '0';
01078
01079 int sl = strlen(line);
01080 if (line[sl-1] != '\n') {
01081 if (sl >= kMAXPATHLEN -1)
01082 line[sl-1] = '\n';
01083 else {
01084 line[sl] = '\n';
01085 line[sl+1] = '\0';
01086 }
01087 }
01088
01089 lseek(itab, pw, SEEK_SET);
01090 while (write(itab, line, strlen(line)) < 0
01091 && GetErrno() == EINTR)
01092 ResetErrno();
01093
01094 lseek(itab, 0, SEEK_END);
01095 }
01096 }
01097 pw = pr;
01098 }
01099
01100
01101 lseek(itab, 0, SEEK_SET);
01102 if (lockf(itab, F_ULOCK, (off_t) 1) == -1) {
01103 ErrorInfo("RpdCleanupAuthTab: error unlocking %s", gRpdAuthTab.c_str());
01104 }
01105
01106 close(itab);
01107
01108 return retval;
01109 }
01110
01111
01112 int RpdCleanupAuthTab(const char *Host, int RemId, int OffSet)
01113 {
01114
01115
01116
01117
01118
01119 int retval = 0;
01120
01121 if (gDebug > 2)
01122 ErrorInfo("RpdCleanupAuthTab: Host: '%s', RemId:%d, OffSet: %d",
01123 Host, RemId, OffSet);
01124
01125
01126 int itab = -1;
01127 if ((itab = open(gRpdAuthTab.c_str(), O_RDWR)) == -1) {
01128 if (GetErrno() == ENOENT) {
01129 if (gDebug > 0)
01130 ErrorInfo("RpdCleanupAuthTab: file %s does not exist",
01131 gRpdAuthTab.c_str());
01132 return -3;
01133 } else {
01134 ErrorInfo("RpdCleanupAuthTab: error opening %s (errno: %d)",
01135 gRpdAuthTab.c_str(), GetErrno());
01136 return -1;
01137 }
01138 }
01139
01140
01141 if (lockf(itab, F_LOCK, (off_t) 1) == -1) {
01142 ErrorInfo("RpdCleanupAuthTab: error locking %s (errno: %d)",
01143 gRpdAuthTab.c_str(), GetErrno());
01144 close(itab);
01145
01146 return -2;
01147 }
01148 if (gDebug > 0)
01149 ErrorInfo("RpdCleanupAuthTab: file LOCKED"
01150 " (Host: '%s', RemId:%d, OffSet: %d)",
01151 Host, RemId, OffSet);
01152
01153
01154 int pr = 0, pw = 0;
01155 int nw, lsec, act, remid, pkey;
01156 char line[kMAXPATHLEN];
01157
01158
01159 int all = (!strcmp(Host, "all") || RemId == 0);
01160
01161
01162 if (all || OffSet < 0)
01163 pr = lseek(itab, 0, SEEK_SET);
01164 else
01165 pr = lseek(itab, OffSet, SEEK_SET);
01166 if (pr < 0) {
01167 ErrorInfo("RpdCleanupAuthTab: error lseeking %s (errno: %d)",
01168 gRpdAuthTab.c_str(), GetErrno());
01169 close(itab);
01170
01171 return -2;
01172 }
01173 pw = pr;
01174 while (reads(itab,line, sizeof(line))) {
01175
01176 pr += strlen(line);
01177 if (gDebug > 2)
01178 ErrorInfo("RpdCleanupAuthTab: pr:%d pw:%d (line:%s) (pId:%d)",
01179 pr, pw, line, gParentId);
01180
01181 char dumm[kMAXPATHLEN], host[kMAXUSERLEN], user[kMAXUSERLEN], shmbuf[30];
01182 nw = sscanf(line, "%d %d %d %d %127s %127s %29s %4095s",
01183 &lsec, &act, &pkey, &remid, host, user, shmbuf, dumm);
01184
01185 if (nw > 5) {
01186 if (all || OffSet > -1 ||
01187 (strstr(line,Host) && (RemId == remid))) {
01188
01189
01190 RpdDeleteKeyFile(pw);
01191
01192 #ifdef R__GLBS
01193 if (lsec == 3 && act > 0) {
01194 int shmid = atoi(shmbuf);
01195 struct shmid_ds shm_ds;
01196 if (shmctl(shmid, IPC_RMID, &shm_ds) == -1) {
01197 if (GetErrno() != EIDRM) {
01198 ErrorInfo("RpdCleanupAuthTab: unable to mark shared"
01199 " memory segment %d (buf:%s)", shmid, shmbuf);
01200 ErrorInfo("RpdCleanupAuthTab: for destruction"
01201 " (errno: %d)", GetErrno());
01202 retval++;
01203 }
01204 }
01205 }
01206 #endif
01207
01208 if (act > 0) {
01209
01210
01211 int slen = (int)strlen(line);
01212 int ka = 0;
01213 while (ka < slen && line[ka] == 32)
01214 ka++;
01215
01216 while (ka < slen && line[ka] != 32)
01217 ka++;
01218
01219 while (ka < slen && line[ka] == 32)
01220 ka++;
01221
01222 line[ka] = '0';
01223
01224 int sl = strlen(line);
01225 if (line[sl-1] != '\n') {
01226 if (sl >= kMAXPATHLEN -1)
01227 line[sl-1] = '\n';
01228 else {
01229 line[sl] = '\n';
01230 line[sl+1] = '\0';
01231 }
01232 }
01233
01234 lseek(itab, pw, SEEK_SET);
01235 while (write(itab, line, strlen(line)) < 0
01236 && GetErrno() == EINTR)
01237 ResetErrno();
01238 if (all || OffSet < 0)
01239 lseek(itab, pr, SEEK_SET);
01240 else
01241 lseek(itab, 0, SEEK_END);
01242 }
01243 }
01244 }
01245 pw = pr;
01246 }
01247
01248
01249 lseek(itab, 0, SEEK_SET);
01250 if (lockf(itab, F_ULOCK, (off_t) 1) == -1) {
01251 ErrorInfo("RpdCleanupAuthTab: error unlocking %s", gRpdAuthTab.c_str());
01252 }
01253
01254 close(itab);
01255
01256 return retval;
01257 }
01258
01259
01260 int RpdCheckAuthTab(int Sec, const char *User, const char *Host, int RemId,
01261 int *OffSet)
01262 {
01263
01264
01265 int retval = 0;
01266 if (gDebug > 2)
01267 ErrorInfo("RpdCheckAuthTab: analyzing: %d %s %s %d %d", Sec, User,
01268 Host, RemId, *OffSet);
01269
01270
01271 char *tkn = 0, *user =0;
01272 int shmid;
01273 bool goodOfs = RpdCheckOffSet(Sec,User,Host,RemId,
01274 OffSet,&tkn,&shmid,&user);
01275 if (gDebug > 2)
01276 ErrorInfo("RpdCheckAuthTab: goodOfs: %d", goodOfs);
01277
01278
01279 int tag = 0;
01280 if (gClientProtocol >= 10) {
01281 if (goodOfs) {
01282 if (gClientProtocol > 11) {
01283
01284 RpdInitRand();
01285 while ((tag = rpd_rand()) == 1) ;
01286
01287
01288 NetSend(tag, kROOTD_AUTH);
01289 } else
01290
01291 NetSend(1, kROOTD_AUTH);
01292 } else {
01293
01294 NetSend(0, kROOTD_AUTH);
01295
01296 if (tkn) delete[] tkn;
01297 if (user) delete[] user;
01298
01299 return retval;
01300 }
01301 }
01302
01303
01304 int ofs = *OffSet;
01305 char *token = 0;
01306 if (gRSAKey > 0) {
01307 if (RpdSecureRecv(&token) == -1) {
01308 ErrorInfo("RpdCheckAuthTab: problems secure-"
01309 "receiving token %s",
01310 "- may result in authentication failure ");
01311 }
01312
01313 } else {
01314 EMessageTypes kind;
01315 int lenToken = 9;
01316 token = new char[lenToken];
01317 NetRecv(token, lenToken, kind);
01318 if (kind != kMESS_STRING)
01319 ErrorInfo
01320 ("RpdCheckAuthTab: got msg kind: %d instead of %d (kMESS_STRING)",
01321 kind, kMESS_STRING);
01322
01323 for (int i = 0; i < (int) strlen(token); i++) {
01324 token[i] = ~token[i];
01325 }
01326 }
01327 if (gDebug > 2)
01328 ErrorInfo
01329 ("RpdCheckAuthTab: received from client: token: '%s' ",
01330 token);
01331
01332
01333 if (token && strlen(token) > 8) {
01334
01335 char tagref[9] = {0};
01336 SPrintf(tagref,9,"%08x",tag);
01337 if (strncmp(token+8,tagref,8)) {
01338 ErrorInfo("RpdCheckAuthTab: token tag does not match - failure");
01339 goodOfs = 0;
01340 } else
01341
01342 token[8] = 0;
01343 }
01344
01345
01346 if (goodOfs && token && RpdCheckToken(token, tkn)) {
01347
01348 if (Sec == 3) {
01349 #ifdef R__GLBS
01350
01351 if (GlbsToolCheckContext(shmid)) {
01352 retval = 1;
01353 strlcpy(gUser, user, sizeof(gUser));
01354 } else {
01355
01356 RpdCleanupAuthTab(Host,RemId,*OffSet);
01357 }
01358 #else
01359 ErrorInfo
01360 ("RpdCheckAuthTab: compiled without Globus support:%s",
01361 " you shouldn't have got here!");
01362 #endif
01363 } else {
01364 retval = 1;
01365 }
01366
01367
01368 if (retval) *OffSet = ofs;
01369 }
01370
01371 if (tkn) delete[] tkn;
01372 if (token) delete[] token;
01373 if (user) delete[] user;
01374
01375 return retval;
01376 }
01377
01378
01379 int RpdCheckOffSet(int Sec, const char *User, const char *Host, int RemId,
01380 int *OffSet, char **Token, int *ShmId, char **GlbsUser)
01381 {
01382
01383
01384 int retval = 0;
01385 bool goodOfs = 0;
01386 int ofs = *OffSet >= 0 ? *OffSet : 0;
01387
01388 if (gDebug > 2)
01389 ErrorInfo("RpdCheckOffSet: analyzing: %d %s %s %d %d", Sec, User,
01390 Host, RemId, *OffSet);
01391
01392
01393 int itab = open(gRpdAuthTab.c_str(), O_RDWR);
01394 if (itab == -1) {
01395 if (GetErrno() == ENOENT)
01396 ErrorInfo("RpcCheckOffSet: file %s does not exist",
01397 gRpdAuthTab.c_str());
01398 else
01399 ErrorInfo("RpcCheckOffSet: error opening %s (errno: %d)",
01400 gRpdAuthTab.c_str(), GetErrno());
01401 return retval;
01402 }
01403
01404 if (lockf(itab, F_LOCK, (off_t) 1) == -1) {
01405 ErrorInfo("RpcCheckOffSet: error locking %s (errno: %d)",
01406 gRpdAuthTab.c_str(), GetErrno());
01407 close(itab);
01408 return retval;
01409 }
01410 if (gDebug > 0)
01411 ErrorInfo("RpdCheckOffSet: file LOCKED");
01412
01413
01414 if (lseek(itab, ofs, SEEK_SET) < 0) {
01415 ErrorInfo("RpcCheckOffSet: error lseeking %s (errno: %d)",
01416 gRpdAuthTab.c_str(), GetErrno());
01417 close(itab);
01418 return retval;
01419 }
01420
01421
01422 char line[kMAXPATHLEN];
01423 if (reads(itab,line, sizeof(line)) < 0) {
01424 ErrorInfo("RpcCheckOffSet: error reading %d bytes from %s (errno: %d)",
01425 sizeof(line), gRpdAuthTab.c_str(), GetErrno());
01426 close(itab);
01427 return retval;
01428 }
01429
01430
01431 int lsec, act, remid, shmid = -1;
01432 char host[kMAXPATHLEN], usr[kMAXPATHLEN], subj[kMAXPATHLEN],
01433 dumm[kMAXPATHLEN], tkn[20];
01434 int nw =
01435 sscanf(line, "%d %d %d %d %4095s %4095s %19s %4095s",
01436 &lsec, &act, &gRSAKey, &remid, host, usr, tkn, dumm);
01437 if (gDebug > 2)
01438 ErrorInfo("RpdCheckOffSet: found line: %s", line);
01439
01440 if (nw > 5 && act > 0) {
01441 if ((lsec == Sec)) {
01442 if (lsec == 3) {
01443 sscanf(line, "%d %d %d %d %4095s %4095s %d %4095s %19s %4095s",
01444 &lsec, &act, &gRSAKey, &remid, host, usr, &shmid, subj, tkn, dumm);
01445 if ((remid == RemId)
01446 && !strcmp(host, Host) && !strcmp(subj, User))
01447 goodOfs = 1;
01448 } else {
01449 if ((remid == RemId) &&
01450 !strcmp(host, Host) && !strcmp(usr, User))
01451 goodOfs = 1;
01452 }
01453 }
01454 }
01455 if (!goodOfs) {
01456
01457 lseek(itab, 0, SEEK_SET);
01458 ofs = 0;
01459 while (reads(itab, line, sizeof(line))) {
01460
01461 nw = sscanf(line, "%d %d %d %d %4095s %4095s %19s %4095s",
01462 &lsec, &act, &gRSAKey, &remid, host, usr, tkn, dumm);
01463 if (gDebug > 2)
01464 ErrorInfo("RpdCheckOffSet: found line: %s", line);
01465
01466 if (nw > 5 && act > 0) {
01467 if (lsec == Sec) {
01468 if (lsec == 3) {
01469 sscanf(line, "%d %d %d %d %4095s %4095s %d %4095s %19s %4095s",
01470 &lsec, &act, &gRSAKey, &remid, host, usr, &shmid, subj, tkn, dumm);
01471 if ((remid == RemId)
01472 && !strcmp(host, Host) && !strcmp(subj, User)) {
01473 goodOfs = 1;
01474 goto found;
01475 }
01476 } else {
01477 if ((remid == RemId) &&
01478 !strcmp(host, Host) && !strcmp(usr, User)) {
01479 goodOfs = 1;
01480 goto found;
01481 }
01482 }
01483 }
01484 }
01485 }
01486 }
01487
01488 found:
01489
01490 lseek(itab, 0, SEEK_SET);
01491 if (lockf(itab, F_ULOCK, (off_t) 1) == -1) {
01492 ErrorInfo("RpcCheckOffSet: error unlocking %s",
01493 gRpdAuthTab.c_str());
01494 }
01495
01496 close(itab);
01497
01498
01499 std::string pukfile = gRpdKeyRoot;
01500 pukfile.append(ItoA(*OffSet));
01501 if (gDebug > 2)
01502 ErrorInfo("RpdCheckOffSet: RSAKey ofs file: %d %d '%s' ",
01503 gRSAKey, ofs, pukfile.c_str());
01504
01505 struct passwd *pw = getpwnam(usr);
01506 if (pw) {
01507 uid_t fromUid = getuid();
01508 uid_t fromEUid = geteuid();
01509
01510
01511
01512 if (fromUid == 0)
01513 if (setresuid(pw->pw_uid, pw->pw_uid, fromEUid) == -1)
01514
01515
01516 goodOfs = 0;
01517
01518
01519 if (goodOfs)
01520 if (RpdGetRSAKeys(pukfile.c_str(), 1) < 1)
01521 goodOfs = 0;
01522
01523
01524 if (getuid() != fromUid)
01525 setresuid(fromUid,fromEUid,pw->pw_uid);
01526
01527 } else {
01528
01529
01530 goodOfs = 0;
01531 if (gDebug > 0)
01532 ErrorInfo("RpdCheckOffSet: error in getpwname(%s) (errno: %d)",
01533 usr,GetErrno());
01534 }
01535
01536 if (gDebug > 2)
01537 ErrorInfo("RpdCheckOffSet: goodOfs: %d (active: %d)",
01538 goodOfs, act);
01539
01540
01541 if (goodOfs) {
01542
01543
01544 if (*OffSet > 0 && *OffSet != ofs) {
01545 if (RpdRenameKeyFile(*OffSet,ofs) > 0) {
01546 goodOfs = 0;
01547
01548 RpdCleanupAuthTab(Host,RemId,ofs);
01549 }
01550 }
01551
01552 *OffSet = ofs;
01553
01554 if (Token) {
01555 *Token = new char[strlen(tkn)+1];
01556 strlcpy(*Token,tkn,strlen(tkn)+1);
01557 }
01558 if (Sec == 3) {
01559 if (GlbsUser) {
01560 *GlbsUser = new char[strlen(usr)+1];
01561 strlcpy(*GlbsUser,usr,strlen(usr)+1);
01562 }
01563 if (ShmId)
01564 *ShmId = shmid;
01565 }
01566 }
01567
01568 return goodOfs;
01569 }
01570
01571
01572 int RpdRenameKeyFile(int oldofs, int newofs)
01573 {
01574
01575
01576
01577 int retval = 0;
01578
01579
01580 std::string oldname = gRpdKeyRoot;
01581 oldname.append(ItoA(oldofs));
01582
01583 std::string newname = gRpdKeyRoot;
01584 newname.append(ItoA(newofs));
01585
01586 if (rename(oldname.c_str(), newname.c_str()) == -1) {
01587 if (gDebug > 0)
01588 ErrorInfo("RpdRenameKeyFile: error renaming key file"
01589 " %s to %s (errno: %d)",
01590 oldname.c_str(),newname.c_str(),GetErrno());
01591 retval = 2;
01592 }
01593
01594 return retval;
01595 }
01596
01597
01598 bool RpdCheckToken(char *token, char *tknref)
01599 {
01600
01601
01602
01603 char *s = strchr(token, '\n');
01604 if (s)
01605 *s = 0;
01606 s = strchr(tknref, '\n');
01607 if (s)
01608 *s = 0;
01609
01610 #ifndef R__NOCRYPT
01611 char *tkn_crypt = crypt(token, tknref);
01612 int tlen = 13;
01613 #else
01614 char *tkn_crypt = rpdcrypt(token,gRndmSalt.c_str());
01615 int tlen = 16;
01616 #endif
01617
01618 if (gDebug > 2)
01619 ErrorInfo("RpdCheckToken: ref:'%s' crypt:'%s'", tknref, tkn_crypt);
01620
01621 if (!strncmp(tkn_crypt, tknref, tlen))
01622 return 1;
01623 else
01624 return 0;
01625 }
01626
01627
01628 int RpdReUseAuth(const char *sstr, int kind)
01629 {
01630
01631
01632
01633
01634 int lenU, offset, opt;
01635 gOffSet = -1;
01636 gExistingAuth = 0;
01637 int auth= 0;
01638
01639 if (gDebug > 2)
01640 ErrorInfo("RpdReUseAuth: analyzing: %s, %d", sstr, kind);
01641
01642 char user[64];
01643
01644
01645 if (kind == kROOTD_USER) {
01646 if (!(gReUseAllow & gAUTH_CLR_MSK)) {
01647 return 0;
01648 }
01649 gSec = 0;
01650
01651 sscanf(sstr, "%d %d %d %d %63s", &gRemPid, &offset, &opt, &lenU, user);
01652 user[lenU] = '\0';
01653 if ((gReUseRequired = (opt & kAUTH_REUSE_MSK))) {
01654 gOffSet = offset;
01655 if (gRemPid > 0 && gOffSet > -1) {
01656 auth =
01657 RpdCheckAuthTab(gSec, user, gOpenHost.c_str(), gRemPid, &gOffSet);
01658 }
01659 if ((auth == 1) && (offset != gOffSet))
01660 auth = 2;
01661
01662 strlcpy(gUser, user, sizeof(gUser));
01663 }
01664 }
01665
01666 if (kind == kROOTD_SRPUSER) {
01667 if (!(gReUseAllow & gAUTH_SRP_MSK)) {
01668 return 0;
01669 }
01670 gSec = 1;
01671
01672 sscanf(sstr, "%d %d %d %d %63s", &gRemPid, &offset, &opt, &lenU, user);
01673 user[lenU] = '\0';
01674 if ((gReUseRequired = (opt & kAUTH_REUSE_MSK))) {
01675 gOffSet = offset;
01676 if (gRemPid > 0 && gOffSet > -1) {
01677 auth =
01678 RpdCheckAuthTab(gSec, user, gOpenHost.c_str(), gRemPid, &gOffSet);
01679 }
01680 if ((auth == 1) && (offset != gOffSet))
01681 auth = 2;
01682
01683 strlcpy(gUser, user, sizeof(gUser));
01684 }
01685 }
01686
01687 if (kind == kROOTD_KRB5) {
01688 if (!(gReUseAllow & gAUTH_KRB_MSK)) {
01689 return 0;
01690 }
01691 gSec = 2;
01692
01693 sscanf(sstr, "%d %d %d %d %63s", &gRemPid, &offset, &opt, &lenU, user);
01694 user[lenU] = '\0';
01695 if ((gReUseRequired = (opt & kAUTH_REUSE_MSK))) {
01696 gOffSet = offset;
01697 if (gRemPid > 0 && gOffSet > -1) {
01698 auth =
01699 RpdCheckAuthTab(gSec, user, gOpenHost.c_str(), gRemPid, &gOffSet);
01700 }
01701 if ((auth == 1) && (offset != gOffSet))
01702 auth = 2;
01703
01704 strlcpy(gUser, user, sizeof(gUser));
01705 }
01706 }
01707
01708 if (kind == kROOTD_GLOBUS) {
01709 if (!(gReUseAllow & gAUTH_GLB_MSK)) {
01710 return 0;
01711 }
01712 gSec = 3;
01713
01714 int lenS;
01715 sscanf(sstr, "%d %d %d %d %63s", &gRemPid, &offset, &opt, &lenS, user);
01716 user[lenS] = '\0';
01717 if ((gReUseRequired = (opt & kAUTH_REUSE_MSK))) {
01718 gOffSet = offset;
01719 if (gRemPid > 0 && gOffSet > -1) {
01720 auth =
01721 RpdCheckAuthTab(gSec, user, gOpenHost.c_str(), gRemPid, &gOffSet);
01722 }
01723 if ((auth == 1) && (offset != gOffSet))
01724 auth = 2;
01725 }
01726 }
01727
01728 if (kind == kROOTD_SSH) {
01729 if (!(gReUseAllow & gAUTH_SSH_MSK)) {
01730 return 0;
01731 }
01732 gSec = 4;
01733
01734 char pipe[kMAXPATHLEN];
01735 sscanf(sstr, "%d %d %d %4095s %d %63s", &gRemPid, &offset, &opt, pipe, &lenU, user);
01736 user[lenU] = '\0';
01737 if ((gReUseRequired = (opt & kAUTH_REUSE_MSK))) {
01738 gOffSet = offset;
01739 if (gRemPid > 0 && gOffSet > -1) {
01740 auth =
01741 RpdCheckAuthTab(gSec, user, gOpenHost.c_str(), gRemPid, &gOffSet);
01742 }
01743 if ((auth == 1) && (offset != gOffSet))
01744 auth = 2;
01745
01746 strlcpy(gUser, user, sizeof(gUser));
01747 }
01748 }
01749
01750
01751 if (auth > 0)
01752 gExistingAuth = 1;
01753
01754
01755 return auth;
01756 }
01757
01758
01759 int RpdCheckAuthAllow(int Sec, const char *Host)
01760 {
01761
01762
01763
01764
01765
01766
01767
01768
01769 int retval = 1, found = 0;
01770
01771 #ifdef R__GBLS
01772 if (Sec == 3 && !gHaveGlobus) {
01773 ErrorInfo("RpdCheckAuthAllow: meth: 3:"
01774 " server does not have globus/GSI credentials");
01775 return 1;
01776 }
01777 #endif
01778
01779 std::string theDaemonRc;
01780
01781
01782 if (getenv("ROOTDAEMONRC"))
01783 theDaemonRc = getenv("ROOTDAEMONRC");
01784
01785 if (theDaemonRc.length() <= 0) {
01786 if (getuid()) {
01787
01788 struct passwd *pw = getpwuid(getuid());
01789 if (pw != 0) {
01790 theDaemonRc = std::string(pw->pw_dir).append("/");
01791 theDaemonRc.append(gDaemonRc);
01792 } else {
01793 if (getenv("ROOTETCDIR")) {
01794 theDaemonRc = std::string(getenv("ROOTETCDIR")).append("/system");
01795 theDaemonRc.append(gDaemonRc);
01796 } else
01797 theDaemonRc = std::string("/etc/root/system").append(gDaemonRc);
01798 }
01799 } else {
01800
01801 if (getenv("ROOTETCDIR")) {
01802 theDaemonRc = std::string(getenv("ROOTETCDIR")).append("/system");
01803 theDaemonRc.append(gDaemonRc);
01804 } else
01805 theDaemonRc = std::string("/etc/root/system").append(gDaemonRc);
01806 }
01807 }
01808 if (gDebug > 2)
01809 ErrorInfo("RpdCheckAuthAllow: Checking file: %s for meth:%d"
01810 " host:%s (gNumAllow: %d)",
01811 theDaemonRc.c_str(), Sec, Host, gNumAllow);
01812
01813
01814 if (gMethInit == 1) {
01815
01816
01817
01818 int newtry = 0, i;
01819 for (i = 0; i < gNumAllow; i++) {
01820 if (gTriedMeth[i] == 0 && gAllowMeth[i] == Sec) {
01821 newtry = 1;
01822 gTriedMeth[i] = 1;
01823 gNumLeft--;
01824 }
01825 }
01826 if (newtry == 0) {
01827 ErrorInfo
01828 ("RpdCheckAuthAllow: new auth method proposed by %s",
01829 " client not in the list or already attempted");
01830 return retval;
01831 }
01832 retval = 0;
01833
01834 } else {
01835
01836
01837 FILE *ftab = fopen(theDaemonRc.c_str(), "r");
01838 if (ftab == 0) {
01839 if (GetErrno() == ENOENT)
01840 ErrorInfo("RpdCheckAuthAllow: file %s does not exist",
01841 theDaemonRc.c_str());
01842 else
01843 ErrorInfo("RpdCheckAuthAllow: error opening %s (errno: %d)",
01844 theDaemonRc.c_str(), GetErrno());
01845 }
01846
01847 char line[kMAXPATHLEN], host[kMAXPATHLEN], rest[kMAXPATHLEN],
01848 cmth[kMAXPATHLEN];
01849 int nmet = 0, mth[6] = { 0 };
01850
01851 int cont = 0, jm = -1;
01852 while (ftab && fgets(line, sizeof(line), ftab)) {
01853 int i;
01854 if (line[0] == '#')
01855 continue;
01856 if (line[strlen(line) - 1] == '\n')
01857 line[strlen(line) - 1] = '\0';
01858
01859 int nw = 0;
01860 char *pstr = line;
01861
01862 if (cont == 1) {
01863 cont = 0;
01864 strlcpy(rest, pstr, kMAXPATHLEN);
01865 } else {
01866 jm = -1;
01867
01868 nw = sscanf(pstr, "%4095s %4095s", host, rest);
01869 if (nw < 2)
01870 continue;
01871 pstr = line + strlen(host) + 1;
01872
01873
01874 char *pcol = strstr(host, ":");
01875 if (pcol) {
01876 if (!strstr(pcol+1, gServName[gService].c_str()))
01877 continue;
01878 else
01879 host[(int)(pcol-host)] = '\0';
01880 }
01881 if (strlen(host) == 0)
01882 strlcpy(host, "default", kMAXPATHLEN);
01883
01884 if (gDebug > 2)
01885 ErrorInfo("RpdCheckAuthAllow: found host: %s ", host);
01886
01887 if (strcmp(host, "default")) {
01888
01889 if (!RpdCheckHost(Host,host)) {
01890 goto next;
01891 }
01892 } else {
01893
01894
01895 if (found == 1)
01896 goto next;
01897 }
01898
01899
01900 nmet = 0;
01901 for (i = 0; i < kMAXSEC; i++) {
01902 mth[i] = -1;
01903 }
01904
01905 }
01906
01907
01908 if (rest[0] == '\\') {
01909 cont = 1;
01910 continue;
01911 }
01912
01913 while (pstr != 0) {
01914 int tmet = -1;
01915 char *pd = 0, *pd2 = 0;
01916 cmth[0] = '\0';
01917 rest[0] = '\0';
01918 nw = sscanf(pstr, "%4095s %4095s", cmth, rest);
01919 if (!strcmp(cmth, "none")) {
01920 nmet = 0;
01921 goto nexti;
01922 }
01923 pd = strchr(cmth, ':');
01924
01925 char tmp[20];
01926 if (pd != 0) {
01927 int mlen = pd - cmth;
01928 strncpy(tmp, cmth, mlen);
01929 tmp[mlen] = '\0';
01930 } else {
01931 strlcpy(tmp, cmth, sizeof(tmp));
01932 }
01933
01934 if (strlen(tmp) > 1) {
01935
01936 for (tmet = 0; tmet < kMAXSEC; tmet++) {
01937 if (!rpdstrcasecmp(gAuthMeth[tmet].c_str(), tmp))
01938 break;
01939 }
01940 if (tmet < kMAXSEC) {
01941 if (gDebug > 2)
01942 ErrorInfo("RpdCheckAuthAllow: tmet %d", tmet);
01943 } else {
01944 if (gDebug > 1)
01945 ErrorInfo("RpdCheckAuthAllow: unknown methods"
01946 " %s - ignore", tmp);
01947 goto nexti;
01948 }
01949
01950 } else {
01951 tmet = atoi(tmp);
01952 }
01953 jm = -1;
01954 if (gDebug > 2)
01955 ErrorInfo("RpdCheckAuthAllow: found method %d (have?:%d)",
01956 tmet, (tmet >= 0 && tmet < kMAXSEC) ? gHaveMeth[tmet] : 0);
01957 if (tmet >= 0 && tmet < kMAXSEC) {
01958 if (gHaveMeth[tmet] == 1) {
01959 int ii;
01960 for (ii = 0; ii < nmet; ii++) {
01961 if (mth[ii] == tmet) {
01962 jm = ii;
01963 }
01964 }
01965 } else
01966 goto nexti;
01967 } else
01968 goto nexti;
01969 if (jm == -1) {
01970
01971 mth[nmet] = tmet;
01972 jm = nmet;
01973 nmet++;
01974 }
01975
01976 while (pd != 0 && (int) (pd[1]) != 32) {
01977 pd2 = strchr(pd + 1, ':');
01978 if (pd[1] == '-') {
01979 pd += 2;
01980
01981 if (gUserIgnore[mth[jm]] == 0) {
01982 gUserIgnLen[mth[jm]] = kMAXPATHLEN;
01983 gUserIgnore[mth[jm]] = new char[gUserIgnLen[mth[jm]]];
01984 gUserIgnore[mth[jm]][0] = '\0';
01985 }
01986 if (strlen(gUserIgnore[mth[jm]]) >
01987 (gUserIgnLen[mth[jm]] - 10)) {
01988 char *tmpUI = strdup(gUserIgnore[mth[jm]]);
01989 free(gUserIgnore[mth[jm]]);
01990 gUserIgnLen[mth[jm]] += kMAXPATHLEN;
01991 gUserIgnore[mth[jm]] = new char[gUserIgnLen[mth[jm]]];
01992 strlcpy(gUserIgnore[mth[jm]], tmpUI, sizeof(gUserIgnLen[mth[jm]]));
01993 free(tmpUI);
01994 }
01995 char usr[256];
01996 if (pd2 != 0) {
01997 int ulen = pd2 - pd;
01998 strncpy(usr, pd, ulen);
01999 usr[ulen] = '\0';
02000 } else {
02001 strlcpy(usr, pd, sizeof(usr));
02002 }
02003 struct passwd *pw = getpwnam(usr);
02004 if (pw != 0)
02005 SPrintf(gUserIgnore[mth[jm]], gUserIgnLen[mth[jm]], "%s %d",
02006 gUserIgnore[mth[jm]], (int)pw->pw_uid);
02007 } else {
02008 pd += 1;
02009 if (pd[1] == '+')
02010 pd += 1;
02011
02012 if (gUserAllow[mth[jm]] == 0) {
02013 gUserAlwLen[mth[jm]] = kMAXPATHLEN;
02014 gUserAllow[mth[jm]] = new char[gUserAlwLen[mth[jm]]];
02015 gUserAllow[mth[jm]][0] = '\0';
02016 }
02017 if (strlen(gUserAllow[mth[jm]]) >
02018 (gUserAlwLen[mth[jm]] - 10)) {
02019 char *tmpUI = strdup(gUserAllow[mth[jm]]);
02020 free(gUserAllow[mth[jm]]);
02021 gUserAlwLen[mth[jm]] += kMAXPATHLEN;
02022 gUserAllow[mth[jm]] = new char[gUserAlwLen[mth[jm]]];
02023 strlcpy(gUserAllow[mth[jm]], tmpUI, sizeof(gUserAlwLen[mth[jm]]));
02024 free(tmpUI);
02025 }
02026 char usr[256];
02027 if (pd2 != 0) {
02028 int ulen = pd2 - pd;
02029 strncpy(usr, pd, ulen);
02030 usr[ulen] = '\0';
02031 } else {
02032 strlcpy(usr, pd, sizeof(usr));
02033 }
02034 struct passwd *pw = getpwnam(usr);
02035 if (pw != 0)
02036 SPrintf(gUserAllow[mth[jm]], gUserIgnLen[mth[jm]], "%s %d",
02037 gUserAllow[mth[jm]], (int)pw->pw_uid);
02038 }
02039 pd = pd2;
02040 }
02041
02042 nexti:
02043 if (nw > 1 && (int) rest[0] != 92) {
02044 pstr = strstr(pstr, rest);
02045 } else {
02046 if ((int) rest[0] == 92)
02047 cont = 1;
02048 pstr = 0;
02049 }
02050 }
02051 if (gDebug > 2) {
02052 ErrorInfo("RpdCheckAuthAllow: for host %s found %d methods",
02053 host, nmet);
02054 ErrorInfo("RpdCheckAuthAllow: %d %d %d %d %d %d", mth[0],
02055 mth[1], mth[2], mth[3], mth[4], mth[5]);
02056 }
02057
02058 found = 1;
02059 retval = 1;
02060 gNumAllow = gNumLeft = nmet;
02061 for (i = 0; i < kMAXSEC; i++) {
02062 gAllowMeth[i] = -1;
02063 gTriedMeth[i] = 0;
02064 if (i < gNumAllow) {
02065 gAllowMeth[i] = mth[i];
02066 if (Sec == mth[i]) {
02067 retval = 0;
02068 gNumLeft--;
02069 gTriedMeth[i] = 1;
02070 }
02071 }
02072 }
02073 next:
02074 continue;
02075 }
02076
02077
02078 if (ftab)
02079 fclose(ftab);
02080
02081
02082 gMethInit = 1;
02083
02084
02085 if (!found) {
02086 if (gDebug > 2)
02087 ErrorInfo
02088 ("RpdCheckAuthAllow: no specific or 'default' entry found: %s",
02089 "using system defaults");
02090 int i;
02091 for (i = 0; i < gNumAllow; i++) {
02092 if (Sec == gAllowMeth[i]) {
02093 retval = 0;
02094 gNumLeft--;
02095 gTriedMeth[i] = 1;
02096 }
02097 }
02098
02099 }
02100
02101 }
02102 if (gDebug > 2) {
02103 ErrorInfo
02104 ("RpdCheckAuthAllow: returning: %d (gNumAllow: %d, gNumLeft:%d)",
02105 retval, gNumAllow, gNumLeft);
02106 int i, jm;
02107 for (i = 0; i < kMAXSEC; i++) {
02108 jm = gAllowMeth[i];
02109 if (gUserAlwLen[jm] > 0)
02110 ErrorInfo("RpdCheckAuthAllow: users allowed for method %d: %s",
02111 jm, gUserAllow[jm]);
02112 }
02113 for (i = 0; i < kMAXSEC; i++) {
02114 jm = gAllowMeth[i];
02115 if (gUserIgnLen[jm] > 0)
02116 ErrorInfo("RpdCheckAuthAllow: users ignored for method %d: %s",
02117 jm, gUserIgnore[jm]);
02118 }
02119 }
02120
02121 return retval;
02122 }
02123
02124
02125 int RpdCheckHost(const char *Host, const char *host)
02126 {
02127
02128
02129
02130
02131 int rc = 1;
02132
02133
02134 if (!Host || !host)
02135 return 0;
02136
02137
02138 if (!strcmp(host,"*"))
02139 return 1;
02140
02141
02142 int name = 0, i = 0;
02143 for (i = 0; i < (int) strlen(host); i++) {
02144 if ((host[i] < 48 || host[i] > 57) &&
02145 host[i] != '*' && host[i] != '.') {
02146 name = 1;
02147 break;
02148 }
02149 }
02150
02151
02152 char *hh;
02153 if (!name) {
02154 hh = RpdGetIP(Host);
02155 if (gDebug > 2)
02156 ErrorInfo("RpdCheckHost: Checking Host IP: %s", hh);
02157 } else {
02158 hh = new char[strlen(Host)+1];
02159 strlcpy(hh,Host,strlen(Host)+1);
02160 if (gDebug > 2)
02161 ErrorInfo("RpdCheckHost: Checking Host name: %s", hh);
02162 }
02163
02164
02165
02166 int sos = 0;
02167 if (host[0] == '*' || host[0] == '.')
02168 sos = 1;
02169
02170
02171
02172 int eos = 0, le = strlen(host);
02173 if (host[le-1] == '*' || host[le-1] == '.')
02174 eos = 1;
02175
02176 int first= 1;
02177 int ends= 0;
02178 int starts= 0;
02179 char *h = new char[strlen(host)+1];
02180 strlcpy(h,host,strlen(host)+1);
02181 char *tk = strtok(h,"*");
02182 while (tk) {
02183
02184 char *ps = strstr(hh,tk);
02185 if (!ps) {
02186 rc = 0;
02187 break;
02188 }
02189 if (!sos && first && ps == hh)
02190 starts = 1;
02191 first = 0;
02192
02193 if (ps == hh + strlen(hh) - strlen(tk))
02194 ends = 1;
02195
02196 tk = strtok(0,"*");
02197
02198 }
02199 delete[] h;
02200 delete[] hh;
02201
02202 if ((!sos || !eos) && !starts && !ends)
02203 rc = 0;
02204
02205 return rc;
02206 }
02207
02208
02209 char *RpdGetIP(const char *host)
02210 {
02211
02212
02213
02214 struct hostent *h;
02215 unsigned long ip;
02216 unsigned char ip_fld[4];
02217
02218
02219 if ((h = gethostbyname(host)) == 0) {
02220 ErrorInfo("RpdGetIP: unknown host %s", host);
02221 return 0;
02222 }
02223
02224 ip = ntohl(*(unsigned long *) h->h_addr_list[0]);
02225 ip_fld[0] = (unsigned char) ((0xFF000000 & ip) >> 24);
02226 ip_fld[1] = (unsigned char) ((0x00FF0000 & ip) >> 16);
02227 ip_fld[2] = (unsigned char) ((0x0000FF00 & ip) >> 8);
02228 ip_fld[3] = (unsigned char) ((0x000000FF & ip));
02229
02230
02231 char *output = new char[20];
02232 SPrintf(output, 20, "%d.%d.%d.%d",
02233 ip_fld[0], ip_fld[1], ip_fld[2], ip_fld[3]);
02234
02235
02236 return output;
02237 }
02238
02239
02240 void RpdSendAuthList()
02241 {
02242
02243
02244 if (gDebug > 2)
02245 ErrorInfo("RpdSendAuthList: analyzing (gNumLeft: %d)", gNumLeft);
02246
02247
02248 NetSend(gNumLeft, kROOTD_NEGOTIA);
02249
02250 if (gNumLeft > 0) {
02251 int i = 0;
02252 std::string alist;
02253 char cm[5];
02254 for (i = 0; i < gNumAllow; i++) {
02255 if (gDebug > 2)
02256 ErrorInfo("RpdSendAuthList: gTriedMeth[%d]: %d", i,
02257 gTriedMeth[i]);
02258 if (gTriedMeth[i] == 0) {
02259 SPrintf(cm, 5, " %d",gAllowMeth[i]);
02260 alist.append(cm);
02261 }
02262 }
02263 NetSend(alist.c_str(), alist.length() + 1, kMESS_STRING);
02264 if (gDebug > 2)
02265 ErrorInfo("RpdSendAuthList: sent list: %s", alist.c_str());
02266 }
02267 }
02268
02269
02270 int RpdSshAuth(const char *sstr)
02271 {
02272
02273
02274 int auth = 0;
02275
02276 if (gDebug > 2)
02277 ErrorInfo("RpdSshAuth: contacted by host: %s for user %s",
02278 gOpenHost.c_str(),sstr);
02279
02280
02281 char user[kMAXUSERLEN];
02282 char pipeId[10] = {0};
02283 int lenU, ofs, opt;
02284 char rproto[20] = {0};
02285 sscanf(sstr, "%d %d %d %9s %d %127s %19s", &gRemPid, &ofs, &opt, pipeId, &lenU, user, rproto);
02286
02287 user[lenU] = '\0';
02288 gReUseRequired = (opt & kAUTH_REUSE_MSK);
02289 #if R__SSL
02290 if (gRSASSLKey) {
02291
02292 gRSAKey = (opt & kAUTH_RSATY_MSK) ? 2 : 1;
02293 } else
02294 gRSAKey = 1;
02295 #else
02296 gRSAKey = 1;
02297 #endif
02298
02299
02300 if (gRemPid < 0) {
02301
02302 if (gDebug > 2)
02303 ErrorInfo
02304 ("RpdSshAuth: this is a failure notification (%s,%s,%d,%s)",
02305 user, gOpenHost.c_str(), gRemPid, pipeId);
02306
02307 struct passwd *pw = getpwnam(user);
02308 if (pw) {
02309 std::string pipeFile =
02310 std::string(pw->pw_dir) + std::string("/RootSshPipe.") + pipeId;
02311 FILE *fpipe = fopen(pipeFile.c_str(), "r");
02312 if (!fpipe) {
02313 pipeFile= gTmpDir + std::string("/RootSshPipe.") + pipeId;
02314 fpipe = fopen(pipeFile.c_str(), "r");
02315 }
02316 char pipe[kMAXPATHLEN];
02317 if (fpipe) {
02318 while (fgets(pipe, sizeof(pipe), fpipe)) {
02319 if (pipe[strlen(pipe)-1] == '\n')
02320 pipe[strlen(pipe)-1] = 0;
02321 }
02322 fclose(fpipe);
02323
02324 unlink(pipeFile.c_str());
02325
02326 if (SshToolNotifyFailure(pipe))
02327 ErrorInfo("RpdSshAuth: failure notification may have"
02328 " failed ");
02329 } else {
02330 if (GetErrno() == ENOENT)
02331 ErrorInfo("RpdSshAuth: pipe file %s does not exists",
02332 pipeFile.c_str());
02333 else
02334 ErrorInfo("RpdSshAuth: cannot open pipe file %s"
02335 " (errno= %d)",pipeFile.c_str(),GetErrno());
02336 }
02337
02338 } else
02339 ErrorInfo("RpdSshAuth: unable to get user info for '%s'"
02340 " (errno: %d)",user,GetErrno());
02341
02342 gClientProtocol = atoi(rproto);
02343
02344
02345
02346 char buf[20] = {0};
02347 #if defined(linux)
02348 if (!RpdCheckSshd(0)) {
02349
02350 if (!RpdCheckSshd(1)) {
02351 if (gDebug > 2)
02352 ErrorInfo("RpdSshAuth: sshd not found - return");
02353 if (gClientProtocol > 9) {
02354 SPrintf(buf, 20, "%d",gSshdPort);
02355 NetSend(strlen(buf), kROOTD_SSH);
02356 NetSend(buf, strlen(buf), kMESS_STRING);
02357 }
02358 return auth;
02359 }
02360 }
02361 #else
02362 if (!RpdCheckSshd(1)) {
02363 if (gDebug > 2)
02364 ErrorInfo("RpdSshAuth: sshd not found - return");
02365 if (gClientProtocol > 9) {
02366 SPrintf(buf, 20,"%d",gSshdPort);
02367 NetSend(strlen(buf), kROOTD_SSH);
02368 NetSend(buf, strlen(buf), kMESS_STRING);
02369 }
02370 return auth;
02371 }
02372 #endif
02373 if (gClientProtocol > 9) {
02374 SPrintf(buf,20,"OK");
02375 NetSend(strlen(buf), kROOTD_SSH);
02376 NetSend(buf, strlen(buf), kMESS_STRING);
02377 ErrorInfo("RpdSshAuth: failure notified");
02378 } else {
02379 NetSend(kErrAuthNotOK,kROOTD_ERR);
02380 ErrorInfo("RpdSshAuth: failure notified");
02381 }
02382 return auth;
02383 }
02384
02385
02386 int sshproto = atoi(rproto);
02387
02388
02389 struct passwd *pw = getpwnam(user);
02390 if (!pw) {
02391 ErrorInfo("RpdSshAuth: entry for user % not found in /etc/passwd",
02392 user);
02393 NetSend(-2, kROOTD_SSH);
02394 return auth;
02395 }
02396
02397 if (!strcmp(pw->pw_shell, "/bin/false")) {
02398 ErrorInfo("RpdSshAuth: no SSH for anonymous user '%s' ", user);
02399 NetSend(-2, kROOTD_SSH);
02400 return auth;
02401 }
02402
02403
02404 char *pipeFile = 0;
02405 char *authFile = 0;
02406 char *uniquePipe = 0;
02407 std::string cmdInfo = "";
02408 int unixFd = -1;
02409 struct stat st0, st1;
02410
02411 if (sshproto == 0) {
02412
02413
02414
02415
02416 if ((unixFd =
02417 SshToolAllocateSocket(pw->pw_uid, pw->pw_gid, &uniquePipe)) < 0) {
02418 ErrorInfo
02419 ("RpdSshAuth: can't allocate UNIX socket for authentication");
02420 NetSend(0, kROOTD_SSH);
02421 delete[] uniquePipe;
02422 return auth;
02423 }
02424
02425
02426 int itmp = 0;
02427 pipeFile = new char[strlen(pw->pw_dir) + 25];
02428 SPrintf(pipeFile, strlen(pw->pw_dir) + 25, "%s/RootSshPipe.XXXXXX", pw->pw_dir);
02429 mode_t oldumask = umask(0700);
02430 int ipipe = mkstemp(pipeFile);
02431 if (ipipe == -1) {
02432 delete[] pipeFile;
02433 pipeFile = new char[gTmpDir.length() + 25];
02434 SPrintf(pipeFile, gTmpDir.length() + 25, "%s/RootSshPipe.XXXXXX", gTmpDir.c_str());
02435 ipipe = mkstemp(pipeFile);
02436 itmp = 1;
02437 }
02438 umask(oldumask);
02439 FILE *fpipe = 0;
02440 if (ipipe == -1 || !(fpipe = fdopen(ipipe,"w")) ) {
02441 ErrorInfo("RpdSshAuth: failure creating pipe file %s (errno: %d)",
02442 pipeFile,GetErrno());
02443
02444
02445 if (SshToolNotifyFailure(uniquePipe))
02446 ErrorInfo("RpdSshAuth: failure notification perhaps"
02447 " unsuccessful ... ");
02448 NetSend(kErrNoPipeInfo, kROOTD_ERR);
02449 delete[] uniquePipe;
02450 delete[] pipeFile;
02451 return auth;
02452 } else {
02453
02454 fprintf(fpipe,"%s\n",uniquePipe);
02455 fclose(fpipe);
02456
02457 chmod(pipeFile, 0600);
02458
02459 if (getuid() == 0)
02460 if (chown(pipeFile,pw->pw_uid,pw->pw_gid) == -1)
02461 ErrorInfo("RpdSshAuth: cannot change ownership of %s (errno: %d)",
02462 pipeFile,GetErrno());
02463 }
02464
02465
02466 char *pId = (char *)strstr(pipeFile,"SshPipe.")+strlen("SshPipe.");
02467 strlcpy(pipeId, pId, sizeof(pipeId));
02468
02469
02470 std::string rootbindir;
02471 if (getenv("ROOTBINDIR"))
02472 rootbindir = getenv("ROOTBINDIR");
02473 char dbgstr[4] = {0};
02474 snprintf(dbgstr,3,"%d ",gDebug);
02475 cmdInfo = std::string(rootbindir).append("/ssh2rpd ");
02476 cmdInfo.append(dbgstr);
02477 cmdInfo.append(" ");
02478 cmdInfo.append(pipeId);
02479
02480
02481 if (itmp) {
02482 cmdInfo.append(" ");
02483 cmdInfo.append(gTmpDir);
02484 }
02485
02486 } else {
02487
02488
02489 authFile = new char[strlen(pw->pw_dir) + 25];
02490 SPrintf(authFile, strlen(pw->pw_dir) + 25, "%s/RootSshAuth.XXXXXX", pw->pw_dir);
02491 mode_t oldumask = umask(0700);
02492 int iauth = mkstemp(authFile);
02493 if (iauth == -1) {
02494 if (gDebug > 2)
02495 ErrorInfo("RpdSshAuth: failure creating Auth file %s (errno: %d)",
02496 authFile,GetErrno());
02497 delete[] authFile;
02498 authFile = new char[gTmpDir.length() + 25];
02499 SPrintf(authFile, gTmpDir.length() + 25, "%s/RootSshAuth.XXXXXX", gTmpDir.c_str());
02500 if ((iauth = mkstemp(authFile)) == -1) {
02501 ErrorInfo("RpdSshAuth: failure creating Auth file %s (errno: %d)",
02502 authFile,GetErrno());
02503 NetSend(kErrFileOpen, kROOTD_ERR);
02504 delete[] authFile;
02505 umask(oldumask);
02506 return auth;
02507 }
02508 }
02509 umask(oldumask);
02510
02511
02512 if (fstat(iauth, &st0) == -1)
02513 ErrorInfo("RpdSshAuth: cannot stat %s",authFile);
02514
02515
02516 if (fchmod(iauth,0600)) {
02517 if (gDebug > 0) {
02518 ErrorInfo("RpdSshAuth: chmod: could not change"
02519 " '%s' permission (errno= %d)",authFile, errno);
02520 ErrorInfo("RpdSshAuth: path (uid,gid) are: %d %d",
02521 st0.st_uid, st0.st_gid);
02522 NetSend(kErrNoChangePermission, kROOTD_ERR);
02523 delete[] authFile;
02524 return auth;
02525 }
02526 }
02527
02528 if ((unsigned int)st0.st_uid != pw->pw_uid ||
02529 (unsigned int)st0.st_gid != pw->pw_gid) {
02530 if (fchown(iauth, pw->pw_uid, pw->pw_gid)) {
02531 if (gDebug > 0) {
02532 ErrorInfo("RpdSshAuth: chown: could not change file"
02533 " '%s' ownership (errno= %d)",authFile, errno);
02534 ErrorInfo("RpdSshAuth: path (uid,gid) are: %d %d",
02535 st0.st_uid, st0.st_gid);
02536 ErrorInfo("RpdSshAuth: may follow authentication problems");
02537 }
02538 }
02539 }
02540
02541
02542 if (fstat(iauth, &st0) == -1)
02543 ErrorInfo("RpdSshAuth: cannot stat %s",authFile);
02544
02545
02546 if (gClientProtocol > 13) {
02547
02548
02549 char hostname[64];
02550 gethostname(hostname, sizeof(hostname));
02551 char *cmd = new char[strlen(authFile) + strlen(user) + strlen(hostname) + 5];
02552 SPrintf(cmd, strlen(authFile) + strlen(user) + strlen(hostname) + 5,
02553 " %s@%s:%s ", user, hostname, authFile);
02554 cmdInfo.append(cmd);
02555 delete[] cmd;
02556 } else {
02557 cmdInfo = std::string(authFile);
02558 }
02559 }
02560
02561
02562 if (gSshdPort != 22) {
02563 char sshp[10];
02564 snprintf(sshp,10," p:%d",gSshdPort);
02565 cmdInfo.append(sshp);
02566 }
02567
02568
02569 if (gRSAKey == 2) {
02570 char key[10];
02571 snprintf(key,10," k:%d",gRSAKey);
02572 cmdInfo.append(key);
02573 }
02574
02575 if (gDebug > 2)
02576 ErrorInfo("RpdSshAuth: sending cmdInfo (%d) %s", cmdInfo.length(),
02577 cmdInfo.c_str());
02578 NetSend(cmdInfo.length(), kROOTD_SSH);
02579 NetSend(cmdInfo.c_str(), cmdInfo.length(), kROOTD_SSH);
02580
02581 if (sshproto == 0) {
02582
02583
02584
02585
02586 auth = SshToolGetAuth(unixFd, user);
02587
02588
02589 SshToolDiscardSocket(uniquePipe, unixFd);
02590
02591 } else {
02592
02593 auth = 0;
02594
02595
02596
02597 EMessageTypes kind;
02598 char res[5];
02599 NetRecv(res, 5, kind);
02600 if (kind != kROOTD_SSH) {
02601 ErrorInfo("RpdSshAuth: expecting message kind: %d"
02602 " - received: %d", (int)kROOTD_SSH, kind);
02603 if (!strncmp(res,"1",1))
02604 NetSend(kErrBadOp, kROOTD_ERR);
02605 if (unlink(authFile) == -1)
02606 if (GetErrno() != ENOENT)
02607 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02608 authFile,GetErrno());
02609 delete[] authFile;
02610
02611 auth = 0;
02612 return auth;
02613 }
02614 if (!strncmp(res,"0",1)) {
02615
02616 if (unlink(authFile) == -1)
02617 if (GetErrno() != ENOENT)
02618 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02619 authFile,GetErrno());
02620 delete[] authFile;
02621
02622 auth = 0;
02623 return auth;
02624 }
02625 if (!strncmp(res,"1",1)) {
02626
02627 FILE *floc = fopen(authFile,"r");
02628 if (!floc) {
02629 ErrorInfo("RpdSshAuth: cannot open auth file:"
02630 " %s (errno: %d)", authFile, GetErrno());
02631 NetSend(kErrFileOpen, kROOTD_ERR);
02632 if (unlink(authFile) == -1)
02633 if (GetErrno() != ENOENT)
02634 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02635 authFile,GetErrno());
02636 delete[] authFile;
02637
02638 auth = 0;
02639 return auth;
02640 }
02641
02642 if (fstat(fileno(floc), &st1) == -1) {
02643 ErrorInfo("RpdSshAuth: cannot fstat descriptor %d", fileno(floc));
02644 fclose(floc);
02645 delete[] authFile;
02646
02647 auth = 0;
02648 return auth;
02649 }
02650
02651 char line[kMAXPATHLEN];
02652 while (fgets(line, sizeof(line), floc) != 0) {
02653
02654 if (line[strlen(line) - 1] == '\n')
02655 line[strlen(line) - 1] = '\0';
02656 if (gDebug > 2)
02657 ErrorInfo("RpdSshAuth: read line ... '%s'", line);
02658 if (!strncmp(line,"k:",2)) {
02659
02660 auth = 1;
02661
02662 char key[4], val[10];
02663 int nw = sscanf(line,"%3s %9s",key,val);
02664 if (nw >= 2 && strncmp(val,"-1",2)) {
02665 gPubKeyLen = fread((void *)gPubKey,1,sizeof(gPubKey),floc);
02666
02667 gRSAKey = RpdGetRSAKeys(gPubKey, 0);
02668 if (gRSAKey == 0) {
02669 ErrorInfo("RpdSshAuth: could not import a valid key");
02670 gReUseRequired = 0;
02671 }
02672 }
02673 }
02674 }
02675 fclose(floc);
02676
02677
02678 if (auth == 0) {
02679
02680
02681
02682 if (gDebug > 2)
02683 ErrorInfo("RpdSshAuth: %d %d",st1.st_ctime,st0.st_ctime);
02684 if (st1.st_ctime != st0.st_ctime)
02685
02686
02687 NetSend(kErrAuthNotOK, kROOTD_ERR);
02688 if (unlink(authFile) == -1)
02689 if (GetErrno() != ENOENT)
02690 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02691 authFile, GetErrno());
02692 delete[] authFile;
02693 return auth;
02694 }
02695 } else {
02696 ErrorInfo("RpdSshAuth: got unknown reply: %s", res);
02697 NetSend(kErrBadMess, kROOTD_ERR);
02698 if (unlink(authFile) == -1)
02699 if (GetErrno() != ENOENT)
02700 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02701 authFile,GetErrno());
02702 delete[] authFile;
02703
02704 auth = 0;
02705 return auth;
02706 }
02707
02708 if (unlink(authFile) == -1)
02709 if (GetErrno() != ENOENT)
02710 ErrorInfo("RpdSshAuth: cannot unlink file %s (errno: %d)",
02711 authFile,GetErrno());
02712 }
02713
02714
02715 if (auth <= 0) {
02716 if (auth == -1)
02717 NetSend(kErrWrongUser, kROOTD_ERR);
02718 else
02719 NetSend(kErrAuthNotOK, kROOTD_ERR);
02720 delete[] uniquePipe;
02721 delete[] pipeFile;
02722
02723 auth = 0;
02724 return auth;
02725 }
02726
02727 if (gDebug > 0 && auth == 1)
02728 ErrorInfo("RpdSshAuth: user %s authenticated by sshd", user);
02729 gSec = 4;
02730
02731
02732 strlcpy(gUser, user, sizeof(gUser));
02733
02734 char line[kMAXPATHLEN];
02735 if ((gReUseAllow & gAUTH_SSH_MSK) && gReUseRequired) {
02736
02737 if (sshproto == 0) {
02738
02739
02740 NetSend(gRSAKey, kROOTD_RSAKEY);
02741
02742
02743 if (RpdRecvClientRSAKey()) {
02744 ErrorInfo("RpdSshAuth: could not import a valid key"
02745 " - switch off reuse for this session");
02746 gReUseRequired = 0;
02747 }
02748 }
02749
02750
02751 int offset = -1;
02752 char *token = 0;
02753 if (gReUseRequired) {
02754 SPrintf(line, kMAXPATHLEN, "4 1 %d %d %s %s",
02755 gRSAKey, gRemPid, gOpenHost.c_str(), gUser);
02756 offset = RpdUpdateAuthTab(1, line, &token);
02757 }
02758
02759 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
02760 NetSend(strlen(line), kROOTD_SSH);
02761 NetSend(line, kMESS_STRING);
02762
02763 if (gReUseRequired && offset > -1) {
02764
02765 if (!token || (token && RpdSecureSend(token) == -1)) {
02766 ErrorInfo
02767 ("RpdSshAuth: problems secure-sending token"
02768 " - may result in corrupted token");
02769 }
02770 if (token) delete[] token;
02771 }
02772 gOffSet = offset;
02773 } else {
02774
02775 SPrintf(line, kMAXPATHLEN, "%s -1", gUser);
02776 NetSend(strlen(line), kROOTD_SSH);
02777 NetSend(line, kMESS_STRING);
02778 }
02779
02780
02781 delete[] uniquePipe;
02782 delete[] pipeFile;
02783 delete[] authFile;
02784
02785 return auth;
02786 }
02787
02788
02789 int RpdKrb5Auth(const char *sstr)
02790 {
02791
02792
02793 int auth = 0;
02794
02795 #ifdef R__KRB5
02796 NetSend(1, kROOTD_KRB5);
02797
02798
02799
02800 int retval;
02801
02802 if (gDebug > 2)
02803 ErrorInfo("RpdKrb5Auth: analyzing ... %s", sstr);
02804
02805 if (gClientProtocol > 8) {
02806 int lenU, ofs, opt;
02807 char dumm[256];
02808
02809 sscanf(sstr, "%d %d %d %d %255s", &gRemPid, &ofs, &opt, &lenU, dumm);
02810 gReUseRequired = (opt & kAUTH_REUSE_MSK);
02811 #if R__SSL
02812 if (gRSASSLKey) {
02813
02814 gRSAKey = (opt & kAUTH_RSATY_MSK) ? 2 : 1;
02815 } else
02816 gRSAKey = 1;
02817 #else
02818 gRSAKey = 1;
02819 #endif
02820 }
02821
02822
02823 retval = krb5_init_context(&gKcontext);
02824 if (retval) {
02825 ErrorInfo("RpdKrb5Auth: %s while initializing krb5",
02826 error_message(retval));
02827 return auth;
02828 }
02829
02830
02831 if (gKeytabFile.length()) {
02832 if ((retval = krb5_kt_resolve(gKcontext, gKeytabFile.c_str(), &gKeytab)))
02833 ErrorInfo("RpdKrb5Auth: %s while resolving keytab file %s",
02834 error_message(retval),gKeytabFile.c_str());
02835 }
02836
02837
02838 const char *service = "host";
02839
02840 if (gDebug > 2)
02841 ErrorInfo("RpdKrb5Auth: using service: %s ",service);
02842
02843 krb5_principal server;
02844 if ((retval = krb5_sname_to_principal(gKcontext, 0, service,
02845 KRB5_NT_SRV_HST, &server))) {
02846 ErrorInfo("RpdKrb5Auth: while generating service name (%s): %d %s",
02847 service, retval, error_message(retval));
02848 RpdFreeKrb5Vars(gKcontext, 0, 0, 0, 0);
02849 return auth;
02850 }
02851
02852
02853 krb5_auth_context auth_context = 0;
02854 krb5_ticket *ticket;
02855 char proto_version[100] = "krootd_v_1";
02856 int sock = NetGetSockFd();
02857
02858 if (gDebug > 2)
02859 ErrorInfo("RpdKrb5Auth: recvauth ... ");
02860
02861 if ((retval = krb5_recvauth(gKcontext, &auth_context,
02862 (krb5_pointer) &sock, proto_version, server,
02863 0, gKeytab,
02864 &ticket))) {
02865 ErrorInfo("RpdKrb5Auth: recvauth failed--%s", error_message(retval));
02866 RpdFreeKrb5Vars(gKcontext, server, 0, 0, 0);
02867 return auth;
02868 }
02869
02870
02871 char *cname;
02872 if ((retval =
02873 krb5_unparse_name(gKcontext, ticket->enc_part2->client, &cname))) {
02874 ErrorInfo("RpdKrb5Auth: unparse failed: %s", error_message(retval));
02875 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, 0);
02876 return auth;
02877 }
02878 if (gDebug > 2)
02879 ErrorInfo("RpdKrb5Auth: name in ticket is: %s",cname);
02880
02881 using std::string;
02882 std::string user = std::string(cname);
02883 free(cname);
02884 std::string reply = std::string("authenticated as ").append(user);
02885
02886
02887
02888 snprintf(gUser,64,"%s",user.c_str());
02889 char *pc = 0;
02890
02891 if ((pc = (char *)strstr(gUser,"@")))
02892 *pc = '\0';
02893
02894 if ((pc = (char *)strstr(gUser,"/")))
02895 *pc = '\0';
02896
02897 std::string targetUser = std::string(gUser);
02898
02899 if (gClientProtocol >= 9) {
02900
02901
02902
02903 if (gDebug > 2)
02904 ErrorInfo("RpdKrb5Auth: receiving target user ... ");
02905
02906 EMessageTypes kind;
02907 char buffer[66];
02908 NetRecv(buffer, 65, kind);
02909
02910 if (kind != kROOTD_KRB5) {
02911 ErrorInfo("RpdKrb5Auth: protocol error, received message"
02912 " of type %d instead of %d\n",kind,kROOTD_KRB5);
02913 }
02914 buffer[65] = 0;
02915 targetUser = std::string(buffer);
02916
02917 if (gDebug > 2)
02918 ErrorInfo("RpdKrb5Auth: received target user %s ",buffer);
02919 }
02920
02921 if (gDebug > 2)
02922 ErrorInfo("RpdKrb5Auth: using ticket file: %s ... ",getenv("KRB5CCNAME"));
02923
02924
02925
02926
02927 if (targetUser != gUser) {
02928 if (krb5_kuserok(gKcontext, ticket->enc_part2->client,
02929 targetUser.c_str())) {
02930 if (gDebug > 2)
02931 ErrorInfo("RpdKrb5Auth: change user from %s to %s successful",
02932 gUser,targetUser.c_str());
02933 snprintf(gUser,64,"%s",targetUser.c_str());
02934 reply = std::string("authenticated as ").append(gUser);
02935 } else {
02936 ErrorInfo("RpdKrb5Auth: could not change user from %s to %s",
02937 gUser,targetUser.c_str());
02938 ErrorInfo("RpdKrb5Auth: continuing with user: %s",gUser);
02939 }
02940 }
02941
02942
02943 if (gClientProtocol >= 9 &&
02944 (gService == kPROOFD || gClientProtocol < 11)) {
02945
02946 char *data = 0;
02947 int size = 0;
02948 if (gDebug > 2)
02949 ErrorInfo("RpdKrb5Auth: receiving forward cred ... ");
02950
02951 {
02952 EMessageTypes kind;
02953 char bufLen[20];
02954 NetRecv(bufLen, 20, kind);
02955
02956 if (kind != kROOTD_KRB5) {
02957 ErrorInfo("RpdKrb5Auth: protocol error, received"
02958 " message of type %d instead of %d\n",
02959 kind, kROOTD_KRB5);
02960 }
02961
02962 size = atoi(bufLen);
02963 if (gDebug > 3)
02964 ErrorInfo("RpdKrb5Auth: got len '%s' %d ", bufLen, size);
02965
02966 data = new char[size+1];
02967
02968
02969 int Nrec = NetRecvRaw(data, size);
02970
02971 if (gDebug > 3)
02972 ErrorInfo("RpdKrb5Auth: received %d ", Nrec);
02973 }
02974
02975 krb5_data forwardCreds;
02976 forwardCreds.data = data;
02977 forwardCreds.length = size;
02978
02979 if (gDebug > 2)
02980 ErrorInfo("RpdKrb5Auth: received forward cred ... %d %d %d",
02981 data[0], data[1], data[2]);
02982
02983 int net = sock;
02984 retval = krb5_auth_con_genaddrs(gKcontext, auth_context, net,
02985 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
02986 if (retval) {
02987 ErrorInfo("RpdKrb5Auth: failed auth_con_genaddrs is: %s\n",
02988 error_message(retval));
02989 }
02990
02991 bool forwarding = true;
02992 krb5_creds **creds = 0;
02993 if ((retval = krb5_rd_cred(gKcontext, auth_context,
02994 &forwardCreds, &creds, 0))) {
02995 ErrorInfo("RpdKrb5Auth: rd_cred failed--%s", error_message(retval));
02996 forwarding = false;
02997 }
02998 if (data) delete[] data;
02999
03000 struct passwd *pw = getpwnam(gUser);
03001 if (forwarding && pw) {
03002 Int_t fromUid = getuid();
03003 Int_t fromEUid = geteuid();
03004
03005 if (setresuid(pw->pw_uid, pw->pw_uid, fromEUid) == -1) {
03006 ErrorInfo("RpdKrb5Auth: can't setuid for user %s", gUser);
03007 NetSend(kErrNotAllowed, kROOTD_ERR);
03008 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03009 return auth;
03010 }
03011
03012 if (gDebug>5)
03013 ErrorInfo("RpdKrb5Auth: saving ticket to cache ...");
03014
03015 krb5_context context;
03016
03017 retval = krb5_init_context(&context);
03018 if (retval) {
03019 ErrorInfo("RpdKrb5Auth: %s while initializing second krb5",
03020 error_message(retval));
03021 NetSend(kErrNotAllowed, kROOTD_ERR);
03022 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03023 return auth;
03024 }
03025
03026 krb5_ccache cache = 0;
03027 char ccacheName[256];
03028 SPrintf(ccacheName,256,"%240s_root_%d",krb5_cc_default_name(context),getpid());
03029 if ((retval = krb5_cc_resolve(context, ccacheName, &cache))) {
03030 ErrorInfo("RpdKrb5Auth: cc_default failed--%s",
03031 error_message(retval));
03032 NetSend(kErrNotAllowed, kROOTD_ERR);
03033 krb5_free_context(context);
03034 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03035 return auth;
03036 }
03037 {
03038 char *ccname = new char[strlen("KRB5CCNAME")+strlen(ccacheName)+2];
03039 SPrintf(ccname, strlen("KRB5CCNAME")+strlen(ccacheName)+2, "KRB5CCNAME=%.*s", strlen(ccacheName), ccacheName);
03040 putenv(ccname);
03041 }
03042
03043 if (gDebug > 5)
03044 ErrorInfo("RpdKrb5Auth: working (1) on ticket to cache (%s) ... ",
03045 krb5_cc_get_name(context,cache));
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056 const char *cacheName = krb5_cc_get_name(context,cache);
03057
03058 if (gDebug>5)
03059 ErrorInfo("RpdKrb5Auth: working (2) on ticket"
03060 " to cache (%s) ... ",cacheName);
03061
03062 if ((retval = krb5_cc_initialize(context,cache,
03063 ticket->enc_part2->client))) {
03064 ErrorInfo("RpdKrb5Auth: cc_initialize failed--%s",
03065 error_message(retval));
03066 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03067 krb5_free_context(context);
03068 NetSend(kErrNotAllowed, kROOTD_ERR);
03069 return auth;
03070 }
03071
03072 if ((retval = krb5_cc_store_cred(context,cache, *creds))) {
03073 ErrorInfo("RpdKrb5Auth: cc_store_cred failed--%s",
03074 error_message(retval));
03075 NetSend(kErrNotAllowed, kROOTD_ERR);
03076 krb5_free_context(context);
03077 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03078 return auth;
03079 }
03080 if (gDebug>5)
03081 ErrorInfo("RpdKrb5Auth: done ticket to cache (%s) ... ",
03082 cacheName);
03083
03084 if ((retval = krb5_cc_close(context,cache))) {
03085 ErrorInfo("RpdKrb5Auth: cc_close failed--%s",
03086 error_message(retval));
03087 NetSend(kErrNotAllowed, kROOTD_ERR);
03088 krb5_free_context(context);
03089 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03090 return auth;
03091 }
03092
03093
03094 krb5_free_context(context);
03095
03096
03097
03098
03099
03100
03101 if (setresuid(fromUid,fromEUid,pw->pw_uid) == -1) {
03102 ErrorInfo("RpdKrb5Auth: can't setuid back to original uid");
03103 NetSend(kErrNotAllowed, kROOTD_ERR);
03104 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, creds);
03105 return auth;
03106 }
03107 }
03108
03109
03110 krb5_free_tgt_creds(gKcontext,creds);
03111 }
03112
03113 NetSend(reply.c_str(), kMESS_STRING);
03114
03115
03116 RpdFreeKrb5Vars(gKcontext, server, ticket, auth_context, (krb5_creds **)0);
03117
03118
03119 auth = 1;
03120 gSec = 2;
03121
03122 if (gClientProtocol > 8) {
03123
03124 char line[kMAXPATHLEN];
03125 if ((gReUseAllow & gAUTH_KRB_MSK) && gReUseRequired) {
03126
03127
03128 NetSend(gRSAKey, kROOTD_RSAKEY);
03129
03130
03131 if (RpdRecvClientRSAKey()) {
03132 ErrorInfo("RpdKrb5Auth: could not import a valid key"
03133 " - switch off reuse for this session");
03134 gReUseRequired = 0;
03135 }
03136
03137
03138
03139 int offset = -1;
03140 char *token = 0;
03141 if (gReUseRequired) {
03142 SPrintf(line, kMAXPATHLEN, "2 1 %d %d %s %s",
03143 gRSAKey, gRemPid, gOpenHost.c_str(), gUser);
03144 offset = RpdUpdateAuthTab(1, line, &token);
03145 if (gDebug > 2)
03146 ErrorInfo("RpdKrb5Auth: line:%s offset:%d", line, offset);
03147 }
03148
03149 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
03150 NetSend(strlen(line), kROOTD_KRB5);
03151 NetSend(line, kMESS_STRING);
03152
03153
03154 if (gReUseRequired && offset > -1) {
03155 if (!token || (token && RpdSecureSend(token) == -1)) {
03156 ErrorInfo("RpdKrb5Auth: problems secure-sending token"
03157 " - may result in corrupted token");
03158 }
03159 if (token) delete[] token;
03160 }
03161 gOffSet = offset;
03162
03163 } else {
03164
03165
03166 SPrintf(line, kMAXPATHLEN, "%s -1", gUser);
03167 NetSend(strlen(line), kROOTD_KRB5);
03168 NetSend(line, kMESS_STRING);
03169
03170 }
03171 } else {
03172 NetSend(user.c_str(), kMESS_STRING);
03173 }
03174
03175 if (gDebug > 0)
03176 ErrorInfo("RpdKrb5Auth: user %s authenticated", gUser);
03177 #else
03178
03179
03180 if (sstr) { }
03181
03182 NetSend(0, kROOTD_KRB5);
03183 #endif
03184
03185 return auth;
03186 }
03187
03188
03189 int RpdSRPUser(const char *sstr)
03190 {
03191
03192
03193
03194 int auth = 0;
03195
03196 if (!*sstr) {
03197 NetSend(kErrBadUser, kROOTD_ERR);
03198 ErrorInfo("RpdSRPUser: bad user name");
03199 return auth;
03200 }
03201
03202 #ifdef R__SRP
03203
03204
03205 char user[kMAXUSERLEN] = { 0 };
03206 if (gClientProtocol > 8) {
03207 int lenU, ofs, opt;
03208 char dumm[20];
03209 sscanf(sstr, "%d %d %d %d %127s %19s", &gRemPid, &ofs, &opt, &lenU, user, dumm);
03210 lenU = (lenU > kMAXUSERLEN) ? kMAXUSERLEN-1 : lenU;
03211 user[lenU] = '\0';
03212 gReUseRequired = (opt & kAUTH_REUSE_MSK);
03213 #if R__SSL
03214 if (gRSASSLKey) {
03215
03216 gRSAKey = (opt & kAUTH_RSATY_MSK) ? 2 : 1;
03217 } else
03218 gRSAKey = 1;
03219 #else
03220 gRSAKey = 1;
03221 #endif
03222 } else {
03223 SPrintf(user,kMAXUSERLEN,"%s",sstr);
03224 }
03225
03226 struct passwd *pw = getpwnam(user);
03227 if (!pw) {
03228 NetSend(kErrNoUser, kROOTD_ERR);
03229 ErrorInfo("RpdSRPUser: user %s unknown", user);
03230 return auth;
03231 }
03232
03233 if (!strcmp(pw->pw_shell, "/bin/false")) {
03234 NetSend(kErrNotAllowed, kROOTD_ERR);
03235 ErrorInfo("RpdSRPUser: no SRP for anonymous user '%s' ", user);
03236 return auth;
03237 }
03238
03239
03240 uid_t uid = getuid();
03241 if (uid && uid != pw->pw_uid) {
03242 NetSend(kErrBadUser, kROOTD_ERR);
03243 ErrorInfo("RpdSRPUser: user not same as effective user of rootd");
03244 return auth;
03245 }
03246
03247 NetSend(auth, kROOTD_AUTH);
03248
03249 strlcpy(gUser, user, sizeof(gUser));
03250
03251 std::string srootdpass, srootdconf;
03252 if (gAltSRPPass.length()) {
03253 srootdpass = gAltSRPPass;
03254 } else {
03255 srootdpass = std::string(pw->pw_dir).append(gSRootdPass);
03256 }
03257 srootdconf = srootdpass + std::string(".conf");
03258
03259 FILE *fp1 = fopen(srootdpass.c_str(), "r");
03260 if (!fp1) {
03261 NetSend(kErrFileOpen, kROOTD_ERR);
03262 ErrorInfo("RpdSRPUser: error opening %s", srootdpass.c_str());
03263 return auth;
03264 }
03265 FILE *fp2 = fopen(srootdconf.c_str(), "r");
03266 if (!fp2) {
03267 NetSend(kErrFileOpen, kROOTD_ERR);
03268 ErrorInfo("RpdSRPUser: error opening %s", srootdconf.c_str());
03269 if (fp1)
03270 fclose(fp1);
03271 return auth;
03272 }
03273
03274 struct t_pw *tpw = t_openpw(fp1);
03275 if (!tpw) {
03276 NetSend(kErrFileOpen, kROOTD_ERR);
03277 ErrorInfo("RpdSRPUser: unable to open password file %s",
03278 srootdpass.c_str());
03279 fclose(fp1);
03280 fclose(fp2);
03281 return auth;
03282 }
03283
03284 struct t_conf *tcnf = t_openconf(fp2);
03285 if (!tcnf) {
03286 NetSend(kErrFileOpen, kROOTD_ERR);
03287 ErrorInfo("RpdSRPUser: unable to open configuration file %s",
03288 srootdconf.c_str());
03289 t_closepw(tpw);
03290 fclose(fp1);
03291 fclose(fp2);
03292 return auth;
03293 }
03294 #if R__SRP_1_1
03295 struct t_server *ts = t_serveropen(gUser, tpw, tcnf);
03296 #else
03297 struct t_server *ts = t_serveropenfromfiles(gUser, tpw, tcnf);
03298 #endif
03299 if (!ts) {
03300 NetSend(kErrNoUser, kROOTD_ERR);
03301 ErrorInfo("RpdSRPUser: user %s not found SRP password file", gUser);
03302 return auth;
03303 }
03304
03305 if (tcnf)
03306 t_closeconf(tcnf);
03307 if (tpw)
03308 t_closepw(tpw);
03309 if (fp2)
03310 fclose(fp2);
03311 if (fp1)
03312 fclose(fp1);
03313
03314 char hexbuf[MAXHEXPARAMLEN];
03315
03316
03317 NetSend(t_tob64(hexbuf, (char *) ts->n.data, ts->n.len), kROOTD_SRPN);
03318
03319 NetSend(t_tob64(hexbuf, (char *) ts->g.data, ts->g.len), kROOTD_SRPG);
03320
03321 NetSend(t_tob64(hexbuf, (char *) ts->s.data, ts->s.len),
03322 kROOTD_SRPSALT);
03323
03324 struct t_num *B = t_servergenexp(ts);
03325
03326
03327 EMessageTypes kind;
03328 if (NetRecv(hexbuf, MAXHEXPARAMLEN, kind) < 0) {
03329 NetSend(kErrFatal, kROOTD_ERR);
03330 ErrorInfo("RpdSRPUser: error receiving A from client");
03331 return auth;
03332 }
03333 if (kind != kROOTD_SRPA) {
03334 NetSend(kErrFatal, kROOTD_ERR);
03335 ErrorInfo("RpdSRPUser: expected kROOTD_SRPA message");
03336 return auth;
03337 }
03338
03339 unsigned char buf[MAXPARAMLEN];
03340 struct t_num A;
03341 A.data = buf;
03342 A.len = t_fromb64((char *) A.data, hexbuf);
03343
03344
03345 NetSend(t_tob64(hexbuf, (char *) B->data, B->len), kROOTD_SRPB);
03346
03347 t_servergetkey(ts, &A);
03348
03349
03350 if (NetRecv(hexbuf, MAXHEXPARAMLEN, kind) < 0) {
03351 NetSend(kErrFatal, kROOTD_ERR);
03352 ErrorInfo("RpdSRPUser: error receiving response from client");
03353 return auth;
03354 }
03355 if (kind != kROOTD_SRPRESPONSE) {
03356 NetSend(kErrFatal, kROOTD_ERR);
03357 ErrorInfo("RpdSRPUser: expected kROOTD_SRPRESPONSE message");
03358 return auth;
03359 }
03360
03361 unsigned char cbuf[20];
03362 t_fromhex((char *) cbuf, hexbuf);
03363
03364 if (!t_serververify(ts, cbuf)) {
03365
03366
03367 if (gDebug > 0)
03368 ErrorInfo("RpdSRPUser: user %s authenticated", gUser);
03369 auth = 1;
03370 gSec = 1;
03371
03372 if (gClientProtocol > 8) {
03373
03374 char line[kMAXPATHLEN];
03375 if ((gReUseAllow & gAUTH_SRP_MSK) && gReUseRequired) {
03376
03377
03378 NetSend(gRSAKey, kROOTD_RSAKEY);
03379
03380
03381 if (RpdRecvClientRSAKey()) {
03382 ErrorInfo
03383 ("RpdSRPAuth: could not import a valid key"
03384 " - switch off reuse for this session");
03385 gReUseRequired = 0;
03386 }
03387
03388
03389 int offset = -1;
03390 char *token = 0;
03391 if (gReUseRequired) {
03392 SPrintf(line, kMAXPATHLEN, "1 1 %d %d %s %s",
03393 gRSAKey, gRemPid, gOpenHost.c_str(), gUser);
03394 offset = RpdUpdateAuthTab(1, line, &token);
03395 }
03396
03397 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
03398 NetSend(strlen(line), kROOTD_SRPUSER);
03399 NetSend(line, kMESS_STRING);
03400
03401 if (gReUseRequired && offset > -1) {
03402
03403 if (RpdSecureSend(token) == -1) {
03404 ErrorInfo("RpdSRPUser: problems secure-sending token"
03405 " - may result in corrupted token");
03406 }
03407 if (token) delete[] token;
03408 }
03409 gOffSet = offset;
03410
03411 } else {
03412
03413 SPrintf(line, kMAXPATHLEN, "%s -1", gUser);
03414 NetSend(strlen(line), kROOTD_SRPUSER);
03415 NetSend(line, kMESS_STRING);
03416 }
03417
03418 }
03419
03420 } else {
03421 if (gClientProtocol > 8) {
03422 NetSend(kErrBadPasswd, kROOTD_ERR);
03423 ErrorInfo("RpdSRPUser: authentication failed for user %s", gUser);
03424 return auth;
03425 }
03426 }
03427
03428 t_serverclose(ts);
03429
03430 #else
03431 NetSend(0, kROOTD_SRPUSER);
03432 #endif
03433 return auth;
03434 }
03435
03436
03437 int RpdCheckHostsEquiv(const char *host, const char *ruser,
03438 const char *user, int &errout)
03439 {
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466 int rc = 0;
03467
03468
03469 int rootuser = 0;
03470 if (!geteuid() && !getegid())
03471 rootuser = 1;
03472
03473
03474
03475 bool badfiles = 0;
03476 int nfiles = 0;
03477
03478
03479 char hostsequiv[20] = { "/etc/hosts.equiv" };
03480 if (!rootuser) {
03481
03482
03483 struct stat st;
03484 if (stat(hostsequiv,&st) == -1) {
03485 if (GetErrno() != ENOENT) {
03486 ErrorInfo("RpdCheckHostsEquiv: cannot stat /etc/hosts.equiv"
03487 " (errno: %d)",GetErrno());
03488 badfiles = 1;
03489 } else
03490 if (gDebug > 1)
03491 ErrorInfo("RpdCheckHostsEquiv: %s does not exist",
03492 hostsequiv);
03493 } else {
03494
03495
03496 if (st.st_uid || st.st_gid) {
03497 if (gDebug > 0)
03498 ErrorInfo("RpdCheckHostsEquiv: /etc/hosts.equiv not owned by"
03499 " system (uid: %d, gid: %d)",st.st_uid,st.st_gid);
03500 badfiles = 1;
03501 } else {
03502
03503
03504 if ((st.st_mode & S_IWGRP) || (st.st_mode & S_IWOTH)) {
03505 if (gDebug > 0)
03506 ErrorInfo("RpdCheckHostsEquiv: group or others have write"
03507 " permission on /etc/hosts.equiv: do not trust"
03508 " it (g: %d, o: %d)",
03509 (st.st_mode & S_IWGRP),(st.st_mode & S_IWOTH));
03510 badfiles = 1;
03511 } else
03512
03513 nfiles++;
03514 }
03515 }
03516 }
03517
03518
03519 char rhosts[kMAXPATHLEN] = {0};
03520 if (!badfiles) {
03521
03522 struct passwd *pw = getpwnam(user);
03523 if (pw) {
03524 int ldir = strlen(pw->pw_dir);
03525 ldir = (ldir > kMAXPATHLEN - 9) ? (kMAXPATHLEN - 9) : ldir;
03526 memcpy(rhosts,pw->pw_dir,ldir);
03527 memcpy(rhosts+ldir,"/.rhosts",8);
03528 rhosts[ldir+8] = 0;
03529 if (gDebug > 2)
03530 ErrorInfo("RpdCheckHostsEquiv: checking for user file %s ...",rhosts);
03531 } else {
03532 if (gDebug > 0)
03533 ErrorInfo("RpdCheckHostsEquiv: cannot get user info with getpwnam"
03534 " (errno: %d)",GetErrno());
03535 badfiles = 1;
03536 }
03537
03538 if (!badfiles) {
03539
03540 struct stat st;
03541 if (stat(rhosts,&st) == -1) {
03542 if (GetErrno() != ENOENT) {
03543 ErrorInfo("RpdCheckHostsEquiv: cannot stat $HOME/.rhosts"
03544 " (errno: %d)",GetErrno());
03545 badfiles = 1;
03546 } else
03547 ErrorInfo("RpdCheckHostsEquiv: %s/.rhosts does not exist",
03548 pw->pw_dir);
03549 } else {
03550
03551
03552 if (!S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) ||
03553 (st.st_mode & 0777) != (S_IRUSR | S_IWUSR)) {
03554 if (gDebug > 0)
03555 ErrorInfo("RpdCheckHostsEquiv: unsecure permission setting"
03556 " found for $HOME/.rhosts: 0%o (must be 0600)",
03557 (st.st_mode & 0777));
03558 badfiles = 1;
03559 } else
03560
03561 nfiles++;
03562 }
03563 }
03564 }
03565
03566
03567
03568 if (!nfiles) {
03569 if (gDebug > 0)
03570 ErrorInfo("RpdCheckHostsEquiv: no files to check");
03571 errout = 1;
03572 if (badfiles) {
03573 if (gDebug > 0)
03574 ErrorInfo("RpdCheckHostsEquiv: config files cannot be used"
03575 " (check permissions)");
03576 errout = 2;
03577 }
03578 return rc;
03579 }
03580
03581
03582
03583 #if defined(__sgi) || defined(_AIX) || defined(__alpha)
03584 if (ruserok((char*)host,rootuser,(char*)ruser,(char*)user) == 0) {
03585 #else
03586 if (ruserok(host,rootuser,ruser,user) == 0) {
03587 #endif
03588 if (gDebug > 0)
03589 ErrorInfo("RpdCheckHostsEquiv: remote user %s authorized to"
03590 " access %s's area",ruser,user);
03591 rc = 1;
03592 } else {
03593 if (gDebug > 0)
03594 ErrorInfo("RpdCheckHostsEquiv: no special permission from"
03595 " %s or %s",hostsequiv,rhosts);
03596 errout = 3;
03597 }
03598
03599 return rc;
03600 }
03601
03602
03603 int RpdCheckSpecialPass(const char *passwd)
03604 {
03605
03606
03607
03608
03609
03610 if (!passwd)
03611 return 0;
03612
03613
03614 if (strlen(gPasswd) <= 0)
03615 return 0;
03616
03617
03618 char *rootdpass = gPasswd;
03619 int n = 0;
03620
03621 if (gClientProtocol > 8 && gSaltRequired > 0) {
03622 n = strlen(rootdpass);
03623 if (strncmp(passwd, rootdpass, n + 1) != 0) {
03624 if (gDebug > 0)
03625 ErrorInfo("RpdCheckSpecialPass: wrong password");
03626 rpdmemset((volatile void *)rootdpass,0,n);
03627 return 0;
03628 }
03629 } else {
03630 #ifndef R__NOCRYPT
03631 char *pass_crypt = crypt(passwd, rootdpass);
03632 #else
03633 char *pass_crypt = (char *)passwd;
03634 #endif
03635 n = strlen(rootdpass);
03636 if (strncmp(pass_crypt, rootdpass, n+1) != 0) {
03637 if (gDebug > 0)
03638 ErrorInfo("RpdCheckSpecialPass: wrong password");
03639 rpdmemset((volatile void *)rootdpass,0,n);
03640 return 0;
03641 }
03642 }
03643
03644 if (gDebug > 0)
03645 ErrorInfo
03646 ("RpdCheckSpecialPass: user %s authenticated via ~/.rootdpass",
03647 gUser);
03648
03649 rpdmemset((volatile void *)rootdpass,0,n);
03650 return 1;
03651 }
03652
03653
03654 int RpdPass(const char *pass, int errheq)
03655 {
03656
03657
03658 char passwd[128];
03659 char *passw;
03660 char *pass_crypt;
03661 struct passwd *pw;
03662 #ifdef R__SHADOWPW
03663 struct spwd *spw;
03664 #endif
03665 int afs_auth = 0;
03666 #ifdef R__AFS
03667 char *reason;
03668 #endif
03669
03670 if (gDebug > 2)
03671 ErrorInfo("RpdPass: Enter (pass length: %d)", (int)strlen(pass));
03672
03673 int auth = 0;
03674 errheq = (errheq > -1 && errheq < 4) ? errheq : 0;
03675 if (!*gUser) {
03676 if (gClientProtocol > 11)
03677 NetSend(gUsrPwdErr[0][errheq], kROOTD_ERR);
03678 else
03679 NetSend(kErrFatal, kROOTD_ERR);
03680 if (gDebug > 0)
03681 ErrorInfo("RpdPass: user needs to be specified first");
03682 return auth;
03683 }
03684
03685 if (!pass) {
03686 if (gClientProtocol > 11)
03687 NetSend(gUsrPwdErr[1][errheq], kROOTD_ERR);
03688 else
03689 NetSend(kErrNoPasswd, kROOTD_ERR);
03690 if (gDebug > 0)
03691 ErrorInfo("RpdPass: no password specified");
03692 return auth;
03693 }
03694 int n = strlen(pass);
03695
03696 if (!n) {
03697 if (gClientProtocol > 11)
03698 NetSend(gUsrPwdErr[1][errheq], kROOTD_ERR);
03699 else
03700 NetSend(kErrBadPasswd, kROOTD_ERR);
03701 if (gDebug > 0)
03702 ErrorInfo("RpdPass: null passwd not allowed");
03703 return auth;
03704 }
03705 if (n > (int) sizeof(passwd)) {
03706 if (gClientProtocol > 11)
03707 NetSend(gUsrPwdErr[1][errheq], kROOTD_ERR);
03708 else
03709 NetSend(kErrBadPasswd, kROOTD_ERR);
03710 if (gDebug > 0)
03711 ErrorInfo("RpdPass: passwd too long");
03712 return auth;
03713 }
03714
03715 strlcpy(passwd, pass, sizeof(passwd));
03716
03717
03718 if (gAnon) {
03719 strlcpy(gPasswd, passwd, sizeof(gPasswd));
03720 goto authok;
03721 }
03722
03723 if (RpdCheckSpecialPass(passwd)) {
03724 goto authok;
03725 }
03726
03727 if (!(pw = getpwnam(gUser))) {
03728 ErrorInfo("RpdPass: getpwnam failed!");
03729 return auth;
03730 }
03731
03732 #ifdef R__AFS
03733 void *tok = GetAFSToken(gUser, passwd, 0, -1, &reason);
03734 afs_auth = (tok) ? 1 : 0;
03735
03736 DeleteAFSToken(tok);
03737 if (!afs_auth) {
03738 if (gDebug > 0)
03739 ErrorInfo("RpdPass: AFS login failed for user %s: %s",
03740 gUser, reason);
03741
03742 #endif
03743
03744 #ifdef R__SHADOWPW
03745
03746 if ((spw = getspnam(gUser)) == 0) {
03747 if (gDebug > 0)
03748 ErrorInfo("RpdPass: Shadow passwd not available for user %s",
03749 gUser);
03750 passw = pw->pw_passwd;
03751 } else
03752 passw = spw->sp_pwdp;
03753 #else
03754 passw = pw->pw_passwd;
03755 #endif
03756 #ifndef R__NOCRYPT
03757 if (gClientProtocol <= 8 || !gSaltRequired) {
03758 char salt[20] = {0};
03759 int lenS = 2;
03760 if (!strncmp(passw, "$1$", 3)) {
03761
03762 char *pd = strstr(passw + 4, "$");
03763 lenS = (int) (pd - passw);
03764 strncpy(salt, passw, lenS);
03765 } else
03766 strncpy(salt, passw, lenS);
03767 salt[lenS] = 0;
03768 pass_crypt = crypt(passwd, salt);
03769 } else {
03770 pass_crypt = passwd;
03771 }
03772 #else
03773 pass_crypt = passwd;
03774 #endif
03775 n = strlen(passw);
03776 if (strncmp(pass_crypt, passw, n + 1) != 0) {
03777 if (gClientProtocol > 11)
03778 NetSend(gUsrPwdErr[1][errheq], kROOTD_ERR);
03779 else
03780 NetSend(kErrBadPasswd, kROOTD_ERR);
03781 if (gDebug > 0)
03782 ErrorInfo("RpdPass: invalid password for user %s", gUser);
03783 return auth;
03784 }
03785 if (gDebug > 2)
03786 ErrorInfo("RpdPass: valid password for user %s", gUser);
03787 #ifdef R__AFS
03788 } else
03789 if (gDebug > 2)
03790 ErrorInfo("RpdPass: AFS login successful for user %s", gUser);
03791 #endif
03792
03793 authok:
03794 auth = afs_auth ? 5 : 1;
03795 gSec = 0;
03796
03797 if (gClientProtocol > 8) {
03798
03799 int offset = -1;
03800 char *token = 0;
03801 char line[kMAXPATHLEN];
03802 if ((gReUseAllow & gAUTH_CLR_MSK) && gReUseRequired) {
03803
03804 SPrintf(line, kMAXPATHLEN, "0 1 %d %d %s %s",
03805 gRSAKey, gRemPid, gOpenHost.c_str(), gUser);
03806 if (!afs_auth || gService == kPROOFD)
03807 offset = RpdUpdateAuthTab(1, line, &token);
03808 if (gDebug > 2)
03809 ErrorInfo("RpdPass: got offset %d", offset);
03810
03811
03812 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
03813 if (gDebug > 2)
03814 ErrorInfo("RpdPass: sending back line %s", line);
03815 NetSend(strlen(line), kROOTD_PASS);
03816 NetSend(line, kMESS_STRING);
03817
03818 if (offset > -1) {
03819 if (gDebug > 2)
03820 ErrorInfo("RpdPass: sending token %s (Crypt: %d)", token,
03821 gCryptRequired);
03822 if (gCryptRequired) {
03823
03824 if (RpdSecureSend(token) == -1) {
03825 if (gDebug > 0)
03826 ErrorInfo("RpdPass: problems secure-sending token"
03827 " - may result in corrupted token");
03828 }
03829 } else {
03830
03831 for (int i = 0; i < (int) strlen(token); i++) {
03832 token[i] = ~token[i];
03833 }
03834 NetSend(token, kMESS_STRING);
03835 }
03836 delete[] token;
03837 }
03838 gOffSet = offset;
03839
03840 } else {
03841
03842 SPrintf(line, kMAXPATHLEN, "%s -1", gUser);
03843 if (gDebug > 2)
03844 ErrorInfo("RpdPass: sending back line %s", line);
03845 NetSend(strlen(line), kROOTD_PASS);
03846 NetSend(line, kMESS_STRING);
03847 }
03848 }
03849
03850 return auth;
03851 }
03852
03853
03854 int RpdGlobusInit()
03855 {
03856
03857
03858
03859 #ifdef R__GLBS
03860
03861
03862
03863
03864
03865
03866
03867
03868 char *subject_name = 0;
03869 int certRc = GlbsToolCheckCert(&subject_name);
03870 if (certRc)
03871 certRc = GlbsToolCheckProxy(&subject_name);
03872 if (certRc) {
03873 ErrorInfo("RpdGlobusInit: no valid server credentials found: globus disabled");
03874 gHaveGlobus = 0;
03875 return 1;
03876 } else {
03877
03878
03879 gGlobusSubjName = subject_name;
03880 delete [] subject_name;
03881
03882
03883
03884
03885
03886 OM_uint32 majStat = 0;
03887 OM_uint32 minStat = 0;
03888 if ((majStat =
03889 globus_gss_assist_acquire_cred(&minStat, GSS_C_ACCEPT,
03890 &gGlbCredHandle)) !=
03891 GSS_S_COMPLETE) {
03892 GlbsToolError("RpdGlobusInit: gss_assist_acquire_cred", majStat,
03893 minStat, 0);
03894 if (getuid() > 0)
03895 ErrorInfo("RpdGlobusInit: non-root: make sure you have"
03896 " initialized (manually) your proxies");
03897 return 1;
03898 }
03899 }
03900 #endif
03901
03902 return 0;
03903 }
03904
03905
03906 int RpdGlobusAuth(const char *sstr)
03907 {
03908
03909
03910 int auth = 0;
03911
03912 #ifndef R__GLBS
03913
03914 if (sstr) { }
03915 NetSend(0, kROOTD_GLOBUS);
03916 return auth;
03917
03918 #else
03919
03920 if (!gHaveGlobus) {
03921
03922 if (sstr) { }
03923 return auth;
03924 }
03925
03926 OM_uint32 MajStat = 0;
03927 OM_uint32 MinStat = 0;
03928 OM_uint32 GssRetFlags = 0;
03929 gss_ctx_id_t GlbContextHandle = GSS_C_NO_CONTEXT;
03930 gss_cred_id_t GlbDelCredHandle = GSS_C_NO_CREDENTIAL;
03931 int GlbTokenStatus = 0;
03932 char *GlbClientName;
03933 FILE *FILE_SockFd;
03934 char *gridmap_default = "/etc/grid-security/grid-mapfile";
03935 EMessageTypes kind;
03936 int lSubj, offset = -1;
03937 char *user = 0;
03938 int ulen = 0;
03939
03940 if (gDebug > 2)
03941 ErrorInfo("RpdGlobusAuth: contacted by host: %s", gOpenHost.c_str());
03942
03943
03944 NetSend(1, kROOTD_GLOBUS);
03945
03946
03947 char Subj[kMAXPATHLEN];
03948 int opt;
03949 char dumm[20];
03950 sscanf(sstr, "%d %d %d %d %4095s %19s", &gRemPid, &offset, &opt, &lSubj, Subj, dumm);
03951
03952 Subj[lSubj] = '\0';
03953 gReUseRequired = (opt & kAUTH_REUSE_MSK);
03954 #if R__SSL
03955 if (gRSASSLKey) {
03956
03957 gRSAKey = (opt & kAUTH_RSATY_MSK) ? 2 : 1;
03958 } else
03959 gRSAKey = 1;
03960 #else
03961 gRSAKey = 1;
03962 #endif
03963 if (gDebug > 2)
03964 ErrorInfo("RpdGlobusAuth: gRemPid: %d, Subj: %s (%d %d)", gRemPid,
03965 Subj, lSubj, strlen(Subj));
03966
03967 if (gClientProtocol < 17) {
03968
03969
03970 char *answer = new char[20];
03971 NetRecv(answer, (int) sizeof(answer), kind);
03972 if (kind != kMESS_STRING) {
03973 Error(gErr, kErrAuthNotOK,
03974 "RpdGlobusAuth: client_issuer_name:received unexpected"
03975 " type of message (%d)",kind);
03976 if (answer) delete[] answer;
03977 return auth;
03978 }
03979 int client_issuer_name_len = atoi(answer);
03980 if (answer) delete[] answer;
03981 char *client_issuer_name = new char[client_issuer_name_len + 1];
03982 NetRecv(client_issuer_name, client_issuer_name_len, kind);
03983 if (kind != kMESS_STRING) {
03984 Error(gErr, kErrAuthNotOK,
03985 "RpdGlobusAuth: client_issuer_name:received unexpected"
03986 " type of message (%d)",kind);
03987 if (client_issuer_name) delete[] client_issuer_name;
03988 return auth;
03989 }
03990 if (gDebug > 2)
03991 ErrorInfo("RpdGlobusAuth: client issuer name is: %s",
03992 client_issuer_name);
03993 }
03994
03995
03996
03997 int sjlen = gGlobusSubjName.length() + 1;
03998 int bsnd = NetSend(sjlen, kROOTD_GLOBUS);
03999 if (gDebug > 2)
04000 ErrorInfo("RpdGlobusAuth: sent: %d (due >=%d))", bsnd, 2 * sizeof(sjlen));
04001 bsnd = NetSend(gGlobusSubjName.c_str(), sjlen, kMESS_STRING);
04002 if (gDebug > 2)
04003 ErrorInfo("RpdGlobusAuth: sent: %d (due >=%d))", bsnd, sjlen);
04004
04005
04006
04007 FILE_SockFd = fdopen(NetGetSockFd(), "w+");
04008
04009
04010 if ((MajStat =
04011 globus_gss_assist_accept_sec_context(&MinStat, &GlbContextHandle,
04012 gGlbCredHandle, &GlbClientName,
04013 &GssRetFlags, 0,
04014 &GlbTokenStatus,
04015 &GlbDelCredHandle,
04016 globus_gss_assist_token_get_fd,
04017 (void *) FILE_SockFd,
04018 globus_gss_assist_token_send_fd,
04019 (void *) FILE_SockFd)) !=
04020 GSS_S_COMPLETE) {
04021 GlbsToolError("RpdGlobusAuth: gss_assist_accept_sec_context",
04022 MajStat, MinStat, GlbTokenStatus);
04023 return auth;
04024 } else {
04025 auth = 1;
04026 gSec = 3;
04027 if (gDebug > 0)
04028 ErrorInfo("RpdGlobusAuth: user: %s \n authenticated",
04029 GlbClientName);
04030 }
04031
04032
04033 if (gService == kPROOFD) {
04034
04035 if (GssRetFlags | GSS_C_DELEG_FLAG) {
04036 if (gDebug > 2)
04037 ErrorInfo("RpdGlobusAuth: Pointer to del cred is %p", GlbDelCredHandle);
04038 } else {
04039 Error(gErr, kErrAuthNotOK,
04040 "RpdGlobusAuth: did not get delegated credentials (RetFlags: 0x%x)",
04041 GssRetFlags);
04042 return auth;
04043 }
04044
04045
04046
04047 gss_buffer_t credential = new gss_buffer_desc;
04048 if ((MajStat =
04049 gss_export_cred(&MinStat, GlbDelCredHandle, 0, 0,
04050 credential)) != GSS_S_COMPLETE) {
04051 GlbsToolError("RpdGlobusAuth: gss_export_cred", MajStat, MinStat,
04052 0);
04053 return auth;
04054 } else if (gDebug > 2)
04055 ErrorInfo("RpdGlobusAuth: credentials prepared for export");
04056
04057
04058 int rc;
04059 if ((rc = GlbsToolStoreToShm(credential, &gShmIdCred))) {
04060 ErrorInfo
04061 ("RpdGlobusAuth: credentials not correctly stored in shm (rc: %d)",
04062 rc);
04063 }
04064 if (gDebug > 2)
04065 ErrorInfo
04066 ("RpdGlobusAuth: credentials stored in shared memory segment %d",
04067 gShmIdCred);
04068
04069 delete credential;
04070 } else {
04071 if (gDebug > 2)
04072 ErrorInfo("RpdGlobusAuth: no need for delegated credentials (%s)",
04073 gServName[gService].c_str());
04074 }
04075
04076
04077
04078 if (getenv("GRIDMAP") == 0) {
04079
04080
04081 setenv("GRIDMAP", gridmap_default, 1);
04082 if (gDebug > 2)
04083 ErrorInfo("RpdGlobusAuth: gridmap: using default file (%s)",
04084 gridmap_default);
04085 } else if (gDebug > 2)
04086 ErrorInfo("RpdGlobusAuth: gridmap: using file %s",
04087 getenv("GRIDMAP"));
04088
04089
04090 char AnonUser[10] = "rootd";
04091 if (globus_gss_assist_gridmap(GlbClientName, &user)) {
04092 if (gDebug > 2)
04093 ErrorInfo
04094 ("RpdGlobusAuth: unable to get local username from gridmap: using: %s",
04095 AnonUser);
04096 user = strdup(AnonUser);
04097 if (gDebug > 2)
04098 ErrorInfo("RpdGlobusAuth: user: %s", user);
04099 }
04100 if (!strcmp(user, "anonymous"))
04101 user = strdup(AnonUser);
04102 if (!strcmp(user, AnonUser))
04103 gAnon = 1;
04104
04105
04106 gReUseRequired = (gAnon == 1) ? 0 : gReUseRequired;
04107
04108
04109 ulen = strlen(user);
04110 strncpy(gUser, user, ulen + 1);
04111
04112 char line[kMAXPATHLEN];
04113 if ((gReUseAllow & gAUTH_GLB_MSK) && gReUseRequired) {
04114
04115
04116 NetSend(gRSAKey, kROOTD_RSAKEY);
04117
04118
04119 if (RpdRecvClientRSAKey()) {
04120 ErrorInfo
04121 ("RpdGlobusAuth: could not import a valid key"
04122 " - switch off reuse for this session");
04123 gReUseRequired = 0;
04124 }
04125
04126
04127 offset = -1;
04128 char *token = 0;
04129 if (gReUseRequired) {
04130 int ShmId = GlbsToolStoreContext(GlbContextHandle, user);
04131 if (ShmId > 0) {
04132 SPrintf(line, kMAXPATHLEN, "3 1 %d %d %s %s %d %s",
04133 gRSAKey, gRemPid, gOpenHost.c_str(),
04134 user, ShmId, GlbClientName);
04135 offset = RpdUpdateAuthTab(1, line, &token);
04136 } else if (gDebug > 0)
04137 ErrorInfo
04138 ("RpdGlobusAuth: unable to export context to shm for later use");
04139 }
04140
04141 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
04142 NetSend(strlen(line), kROOTD_GLOBUS);
04143 NetSend(line, kMESS_STRING);
04144
04145 if (gReUseRequired && offset > -1) {
04146
04147 if (RpdSecureSend(token) == -1) {
04148 ErrorInfo("RpdGlobusAuth: problems secure-sending token"
04149 " - may result in corrupted token");
04150 }
04151 if (token) delete[] token;
04152 }
04153 gOffSet = offset;
04154 } else {
04155
04156 SPrintf(line, kMAXPATHLEN, "%s %d", gUser, offset);
04157 NetSend(strlen(line), kROOTD_GLOBUS);
04158 NetSend(line, kMESS_STRING);
04159 }
04160
04161
04162 free(user);
04163 free(GlbClientName);
04164
04165 if (gDebug > 0)
04166 ErrorInfo("RpdGlobusAuth: client mapped to local user %s ", gUser);
04167
04168 return auth;
04169
04170 #endif
04171 }
04172
04173
04174 int RpdRfioAuth(const char *sstr)
04175 {
04176
04177
04178
04179
04180 int auth = 0;
04181
04182 if (gDebug > 2)
04183 ErrorInfo("RpdRfioAuth: analyzing ... %s", sstr);
04184
04185 if (!*sstr) {
04186 NetSend(kErrBadUser, kROOTD_ERR);
04187 ErrorInfo("RpdRfioAuth: subject string is empty");
04188 return auth;
04189 }
04190
04191 unsigned int uid, gid;
04192 sscanf(sstr, "%u %u", &uid, &gid);
04193
04194
04195 struct passwd *pw;
04196 if ((pw = getpwuid((uid_t) uid)) == 0) {
04197 NetSend(kErrBadUser, kROOTD_ERR);
04198 ErrorInfo("RpdRfioAuth: uid %u not found", uid);
04199 return auth;
04200 }
04201
04202 char cuid[20];
04203 SPrintf(cuid, 20, "%u", uid);
04204 if (gUserIgnLen[5] > 0 && strstr(gUserIgnore[5], cuid) != 0) {
04205 NetSend(kErrNotAllowed, kROOTD_ERR);
04206 ErrorInfo
04207 ("RpdRfioAuth: user (%u,%s) not authorized to use (uid:gid) method",
04208 uid, pw->pw_name);
04209 return auth;
04210 }
04211 if (gUserAlwLen[5] > 0 && strstr(gUserAllow[5], cuid) == 0) {
04212 NetSend(kErrNotAllowed, kROOTD_ERR);
04213 ErrorInfo
04214 ("RpdRfioAuth: user (%u,%s) not authorized to use (uid:gid) method",
04215 uid, pw->pw_name);
04216 return auth;
04217 }
04218
04219
04220 if (gid != (unsigned int) pw->pw_gid) {
04221 NetSend(kErrBadUser, kROOTD_ERR);
04222 ErrorInfo
04223 ("RpdRfioAuth: group id does not match (remote:%u,local:%u)",
04224 gid, (unsigned int) pw->pw_gid);
04225 return auth;
04226 }
04227
04228 strlcpy(gUser, pw->pw_name, sizeof(gUser));
04229
04230
04231
04232 if (gDebug > 0)
04233 ErrorInfo("RpdRfioAuth: user %s authenticated (uid:%u, gid:%u)",
04234 gUser, uid, gid);
04235
04236
04237 auth = 1;
04238 gSec = 5;
04239
04240 return auth;
04241 }
04242
04243
04244 void RpdAuthCleanup(const char *sstr, int opt)
04245 {
04246
04247
04248
04249
04250 int rpid = 0, sec = -1, offs = -1, nw = 0;
04251 char usr[64] = {0};
04252 if (sstr)
04253 nw = sscanf(sstr, "%d %d %d %63s", &rpid, &sec, &offs, usr);
04254
04255
04256 if (getuid() == 0) {
04257 if (setresgid(0, 0, 0) == -1)
04258 if (gDebug > 0)
04259 ErrorInfo("RpdAuthCleanup: can't setgid to superuser");
04260 if (setresuid(0, 0, 0) == -1)
04261 if (gDebug > 0)
04262 ErrorInfo("RpdAuthCleanup: can't setuid to superuser");
04263 }
04264 if (opt == 0) {
04265 RpdCleanupAuthTab("all", 0, -1);
04266 ErrorInfo("RpdAuthCleanup: cleanup ('all',0) done");
04267 } else if (opt == 1) {
04268 if (nw == 1) {
04269
04270 RpdCleanupAuthTab(gOpenHost.c_str(), rpid, -1);
04271 ErrorInfo("RpdAuthCleanup: cleanup ('%s',%d) done",
04272 gOpenHost.c_str(), rpid);
04273 } else if (nw == 4) {
04274
04275 if (RpdCheckOffSet(sec,usr,gOpenHost.c_str(),rpid,&offs,0,0,0)) {
04276 RpdCleanupAuthTab(gOpenHost.c_str(), rpid, offs);
04277 ErrorInfo("RpdAuthCleanup: cleanup (%s,%d,%d,%d,%s) done",
04278 gOpenHost.c_str(), rpid, sec, offs, usr);
04279 } else {
04280 ErrorInfo("RpdAuthCleanup: cleanup not done: %s",
04281 "wrong offset or already cleaned up");
04282 }
04283 }
04284 }
04285 }
04286
04287
04288 void RpdInitAuth()
04289 {
04290
04291
04292
04293
04294 int i;
04295 gNumAllow = gNumLeft = 0;
04296 for (i = 0; i < kMAXSEC; i++) {
04297 gAllowMeth[i] = -1;
04298 gHaveMeth[i] = 1;
04299 }
04300
04301
04302 RpdDefaultAuthAllow();
04303 }
04304
04305
04306 void RpdDefaultAuthAllow()
04307 {
04308
04309
04310
04311 if (gDebug > 2)
04312 ErrorInfo("RpdDefaultAuthAllow: Enter");
04313
04314
04315 gAllowMeth[gNumAllow] = 0;
04316 gNumAllow++;
04317 gNumLeft++;
04318
04319
04320 gAllowMeth[gNumAllow] = 4;
04321 gNumAllow++;
04322 gNumLeft++;
04323
04324
04325 #ifdef R__SRP
04326 gAllowMeth[gNumAllow] = 1;
04327 gNumAllow++;
04328 gNumLeft++;
04329 #else
04330
04331 gHaveMeth[1] = 0;
04332 #endif
04333
04334
04335 #ifdef R__KRB5
04336 gAllowMeth[gNumAllow] = 2;
04337 gNumAllow++;
04338 gNumLeft++;
04339 #else
04340
04341 gHaveMeth[2] = 0;
04342 #endif
04343
04344
04345 #ifdef R__GLBS
04346 gAllowMeth[gNumAllow] = 3;
04347 gNumAllow++;
04348 gNumLeft++;
04349 #else
04350
04351 gHaveMeth[3] = 0;
04352 #endif
04353
04354 if (gDebug > 2) {
04355 int i;
04356 std::string temp;
04357 char cm[5];
04358 if (gNumAllow == 0)
04359 temp.append("none");
04360 for (i = 0; i < gNumAllow; i++) {
04361 SPrintf(cm, 5, " %3d",gAllowMeth[i]);
04362 temp.append(cm);
04363 }
04364 ErrorInfo
04365 ("RpdDefaultAuthAllow: default list of secure methods available: %s",
04366 temp.c_str());
04367 }
04368 }
04369
04370
04371 int RpdCheckDaemon(const char *daemon)
04372 {
04373
04374
04375
04376 char cmd[kMAXPATHLEN] = { 0 };
04377 int ch, i = 0, cnt = 0;
04378
04379 if (gDebug > 2)
04380 ErrorInfo("RpdCheckDaemon: Enter ... %s", daemon);
04381
04382
04383 if (daemon == 0 || strlen(daemon) == 0)
04384 return cnt;
04385
04386
04387 SPrintf(cmd, kMAXPATHLEN, "ps ax | grep %s 2>/dev/null", daemon);
04388
04389
04390 FILE *fp = popen(cmd, "r");
04391 if (fp != 0) {
04392 for (ch = fgetc(fp); ch != EOF; ch = fgetc(fp)) {
04393 if (ch != 10) {
04394 cmd[i++] = ch;
04395 } else {
04396 cmd[i] = '\0';
04397 if (strstr(cmd, "grep") == 0 && strstr(cmd, "rootd") == 0
04398 && strstr(cmd, "proofd") == 0) {
04399 cnt++;
04400 }
04401 i = 0;
04402 }
04403 }
04404 if (i > 0) {
04405 cmd[i] = '\0';
04406 cnt++;
04407 }
04408 pclose(fp);
04409 if (gDebug > 2)
04410 ErrorInfo("RpdCheckDaemon: found %d instances of daemon %s",
04411 cnt, daemon);
04412
04413 } else {
04414 ErrorInfo("RpdCheckDaemon: problems executing cmd ...");
04415 }
04416 return cnt;
04417 }
04418
04419
04420 int RpdCheckSshd(int opt)
04421 {
04422
04423
04424
04425 if (gDebug > 2)
04426 ErrorInfo("RpdCheckSshd: Enter ... ");
04427
04428 int rc = 0;
04429 if (opt == 0) {
04430
04431
04432
04433
04434
04435
04436 char cs[20];
04437 SPrintf(cs, 20, ":%d",gSshdPort);
04438
04439
04440 char cmd[kMAXPATHLEN] = { 0 };
04441 SPrintf(cmd, kMAXPATHLEN,
04442 "netstat -apn 2>/dev/null | grep LISTEN | grep -v LISTENING");
04443 FILE *fp= popen(cmd,"r");
04444 if (fp != 0) {
04445 while (fgets(cmd, sizeof(cmd), fp) != 0) {
04446 if (gDebug > 3)
04447 ErrorInfo("RpdCheckSshd: read: %s",cmd);
04448 if (strstr(cmd,cs)) {
04449 rc = 1;
04450 break;
04451 }
04452 }
04453 pclose(fp);
04454 } else {
04455 ErrorInfo("RpdCheckSshd: Problems executing 'netstat' ...");
04456 }
04457
04458 if (gDebug > 2 && rc) {
04459 ErrorInfo("RpdCheckSshd: %s: %s %d", "diagnostics report",
04460 "something is listening on port", gSshdPort);
04461 }
04462
04463 if (!rc) {
04464 ErrorInfo("RpdCheckSshd: nothing seem to listening on port %d",
04465 gSshdPort);
04466 }
04467
04468 } else if (opt == 1) {
04469
04470
04471
04472
04473
04474
04475 struct hostent *h = gethostbyname("localhost");
04476 if (h == 0) {
04477
04478 if (getenv("HOSTNAME") == 0) {
04479 ErrorInfo("RpdCheckSshd: unable to resolve local host name");
04480 return 0;
04481 } else {
04482 h = gethostbyname(getenv("HOSTNAME"));
04483 if (h == 0) {
04484 ErrorInfo
04485 ("RpdCheckSshd: local host name is unknown to gethostbyname: '%s'",
04486 getenv("HOSTNAME"));
04487 return 0;
04488 }
04489 }
04490 }
04491
04492
04493 struct sockaddr_in servAddr;
04494 servAddr.sin_zero[0] = 0;
04495 servAddr.sin_family = h->h_addrtype;
04496 memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0],
04497 h->h_length);
04498 servAddr.sin_port = htons(gSshdPort);
04499
04500
04501 int sd = socket(AF_INET, SOCK_STREAM, 0);
04502 if (sd < 0) {
04503 ErrorInfo("RpdCheckSshd: cannot open new AF_INET socket (errno:%d) ",
04504 errno);
04505 return 0;
04506 }
04507
04508
04509 struct sockaddr_in localAddr;
04510 localAddr.sin_zero[0] = 0;
04511 localAddr.sin_family = AF_INET;
04512 localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
04513 localAddr.sin_port = htons(0);
04514 if (bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr)) < 0) {
04515 ErrorInfo("RpdCheckSshd: cannot bind to local port %u", gSshdPort);
04516 return 0;
04517 }
04518
04519 if (connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
04520 ErrorInfo("RpdCheckSshd: cannot connect to local port %u",
04521 gSshdPort);
04522 return 0;
04523 }
04524
04525 if (gDebug > 2)
04526 ErrorInfo("RpdCheckSshd: success!");
04527 rc = 1;
04528 }
04529
04530 return rc;
04531 }
04532
04533
04534 int RpdUser(const char *sstr)
04535 {
04536
04537
04538 const int kMaxBuf = 256;
04539 char recvbuf[kMaxBuf];
04540 EMessageTypes kind;
04541 struct passwd *pw;
04542 if (gDebug > 2)
04543 ErrorInfo("RpdUser: Enter ... %s", sstr);
04544
04545 int auth = 0;
04546
04547
04548 if (!*sstr) {
04549 NetSend(kErrBadUser, kROOTD_ERR);
04550 ErrorInfo("RpdUser: received empty string");
04551 return auth;
04552 }
04553
04554 char user[kMAXUSERLEN] = {0};
04555 char ruser[kMAXUSERLEN] = {0};
04556 if (gClientProtocol > 8) {
04557 int ulen, ofs, opt, rulen;
04558
04559 int nw = sscanf(sstr, "%d %d %d %d %63s %d %63s",
04560 &gRemPid, &ofs, &opt, &ulen, user, &rulen, ruser);
04561 ulen = (ulen >= kMAXUSERLEN) ? kMAXUSERLEN-1 : ulen;
04562 rulen = (rulen >= kMAXUSERLEN) ? kMAXUSERLEN-1 : rulen;
04563 user[ulen] = '\0';
04564 if (nw > 5)
04565 ruser[rulen] = '\0';
04566 gReUseRequired = (opt & kAUTH_REUSE_MSK);
04567 gCryptRequired = (opt & kAUTH_CRYPT_MSK);
04568 gSaltRequired = (opt & kAUTH_SSALT_MSK);
04569 gOffSet = ofs;
04570 #if R__SSL
04571 if (gRSASSLKey) {
04572
04573 gRSAKey = (opt & kAUTH_RSATY_MSK) ? 2 : 1;
04574 } else
04575 gRSAKey = 1;
04576 #else
04577 gRSAKey = 1;
04578 #endif
04579 } else {
04580 SPrintf(user,kMAXUSERLEN,"%s",sstr);
04581 }
04582 if (gDebug > 2)
04583 ErrorInfo("RpdUser: gReUseRequired: %d gCryptRequired: %d gRSAKey: %d",
04584 gReUseRequired, gCryptRequired, gRSAKey);
04585
04586 ERootdErrors err = kErrNoUser;
04587 if (gService == kROOTD) {
04588
04589 if (!strcmp(user, "anonymous")) {
04590 user[0] = '\0';
04591 strlcpy(user, "rootd", sizeof(user));
04592 }
04593 }
04594
04595 if ((pw = getpwnam(user)) == 0) {
04596 NetSend(err, kROOTD_ERR);
04597 ErrorInfo("RpdUser: user %s unknown", user);
04598 return auth;
04599 }
04600
04601
04602
04603 uid_t uid = getuid();
04604 if (uid && uid != pw->pw_uid) {
04605 NetSend(kErrBadUser, kROOTD_ERR);
04606 ErrorInfo("RpdUser: user not same as effective user of rootd");
04607 return auth;
04608 }
04609
04610
04611 char cuid[20];
04612 SPrintf(cuid, 20, "%d", (int)pw->pw_uid);
04613 if (gUserIgnLen[0] > 0 && strstr(gUserIgnore[0], cuid) != 0) {
04614 NetSend(kErrNotAllowed, kROOTD_ERR);
04615 ErrorInfo
04616 ("RpdUser: user (%d,%s) not authorized to use UsrPwd method",
04617 uid, pw->pw_name);
04618 return auth;
04619 }
04620 if (gUserAlwLen[0] > 0 && strstr(gUserAllow[0], cuid) == 0) {
04621 NetSend(kErrNotAllowed, kROOTD_ERR);
04622 ErrorInfo
04623 ("RpdUser: user (%d,%s) not authorized to use UsrPwd method",
04624 uid, pw->pw_name);
04625 return auth;
04626 }
04627
04628
04629 int errheq = 0;
04630 if (gCheckHostsEquiv && strlen(ruser)) {
04631 if (RpdCheckHostsEquiv(gOpenHost.c_str(),ruser,user,errheq)) {
04632 auth = 3;
04633 strlcpy(gUser, user, sizeof(gUser));
04634 return auth;
04635 }
04636 }
04637
04638
04639 if (!strcmp(pw->pw_shell, "/bin/false")) {
04640 err = kErrNoAnon;
04641 gAnon = 1;
04642 gReUseRequired = 0;
04643 }
04644
04645
04646
04647
04648
04649
04650 gPasswd[0] = 0;
04651 char *passw = gPasswd;
04652 int errrdp = 0;
04653 if (gAnon == 0) {
04654
04655
04656 int rcsp = RpdRetrieveSpecialPass(user,gRootdPass.c_str(),
04657 gPasswd,sizeof(gPasswd));
04658 if (rcsp < 0)
04659 errrdp = (rcsp == -2) ? 3 : 0;
04660
04661 if (strlen(passw) == 0 || !strcmp(passw, "x")) {
04662 #ifdef R__AFS
04663 gSaltRequired = 0;
04664 #else
04665
04666 #ifdef R__SHADOWPW
04667 struct spwd *spw = 0;
04668
04669 if ((spw = getspnam(user)) == 0) {
04670 if (gDebug > 0) {
04671 ErrorInfo("RpdUser: Shadow passwd not accessible for user %s",user);
04672 ErrorInfo("RpdUser: trying normal system passwd");
04673 }
04674 } else
04675 passw = spw->sp_pwdp;
04676 #else
04677 passw = pw->pw_passwd;
04678 #endif
04679
04680 if (strlen(passw) == 0 || !strcmp(passw, "x")) {
04681 if (gClientProtocol > 11)
04682 NetSend(gUsrPwdErr[errrdp][errheq], kROOTD_ERR);
04683 else
04684 NetSend(kErrNotAllowed, kROOTD_ERR);
04685 ErrorInfo("RpdUser: passwd hash not available for user %s", user);
04686 ErrorInfo
04687 ("RpdUser: user %s cannot be authenticated with this method",
04688 user);
04689 return auth;
04690 }
04691 #endif
04692 }
04693 }
04694
04695 strlcpy(gUser, user, sizeof(gUser));
04696
04697
04698 char salt[30] = { 0 };
04699 char ctag[11] = { 0 };
04700 int rtag = 0;
04701 int lenS = 0;
04702
04703 if (gClientProtocol > 8) {
04704
04705
04706 if (gAnon == 1) {
04707
04708
04709 NetSend(-1, kROOTD_AUTH);
04710
04711 } else {
04712
04713 if (gCryptRequired) {
04714
04715
04716 NetSend(gRSAKey, kROOTD_RSAKEY);
04717
04718
04719 if (RpdRecvClientRSAKey()) {
04720 ErrorInfo("RpdUser: could not import a valid key -"
04721 " switch off reuse for this session");
04722 gReUseRequired = 0;
04723 }
04724
04725
04726 if (gClientProtocol > 11) {
04727 RpdInitRand();
04728 rtag = rpd_rand();
04729 SPrintf(ctag, 11, "#%08x#",rtag);
04730 }
04731
04732 if (gSaltRequired) {
04733
04734
04735 if (passw[0] == '$' && passw[2] == '$') {
04736
04737 char *pd = strstr(passw + 4, "$");
04738 lenS = (int) (pd - passw);
04739 strncpy(salt, passw, lenS);
04740 salt[lenS] = 0;
04741 } else {
04742 lenS = 2;
04743 strncpy(salt, passw, lenS);
04744 salt[lenS] = 0;
04745 }
04746 if (gDebug > 2)
04747 ErrorInfo("RpdUser: salt: '%s' ",salt);
04748
04749
04750 if (gClientProtocol > 11) {
04751 strncpy(&salt[lenS],ctag,10);
04752 salt[lenS+10] = 0;
04753 }
04754
04755
04756 if (RpdSecureSend(salt) == -1) {
04757 ErrorInfo("RpdUser: problems secure-sending salt -"
04758 " may result in corrupted salt");
04759 }
04760 } else {
04761 if (gClientProtocol > 11) {
04762
04763 if (RpdSecureSend(ctag) == -1) {
04764 ErrorInfo("RpdUser: problems secure-sending rndmtag -"
04765 " may result in corrupted rndmtag");
04766 }
04767 } else
04768 NetSend(0, kMESS_ANY);
04769 }
04770 } else {
04771
04772 NetSend(0, kROOTD_AUTH);
04773 }
04774 }
04775
04776 } else {
04777
04778 NetSend(0, kROOTD_AUTH);
04779 }
04780
04781
04782 if (NetRecv(recvbuf, kMaxBuf, kind) < 0) {
04783 NetSend(kErrFatal, kROOTD_ERR);
04784 ErrorInfo("RpdUser: error receiving message");
04785 return auth;
04786 }
04787 if (kind != kROOTD_PASS) {
04788 NetSend(kErrFatal, kROOTD_ERR);
04789 ErrorInfo("RpdUser: received wrong message type: %d (expecting: %d)",
04790 kind, (int) kROOTD_PASS);
04791 return auth;
04792 }
04793 if (!strncmp(recvbuf,"-1",2)) {
04794 if (gDebug > 0)
04795 ErrorInfo("RpdUser: client did not send a password - return");
04796 return auth;
04797 }
04798
04799 char *passwd = 0;
04800 int lpwd = 0;
04801 if (gAnon == 0 && gClientProtocol > 8 && gCryptRequired) {
04802
04803
04804 if (RpdSecureRecv(&passwd) == -1) {
04805 ErrorInfo
04806 ("RpdUser: problems secure-receiving pass hash - %s",
04807 "may result in authentication failure");
04808 }
04809
04810 lpwd = strlen(passwd);
04811
04812
04813 if (strlen(ctag)) {
04814
04815
04816 int plen = lpwd;
04817 if (plen > 9 &&
04818 passwd[plen-1] == '#' && passwd[plen-10] == '#') {
04819 if (strncmp(ctag,&passwd[plen-10],10)) {
04820
04821 if (gClientProtocol > 11)
04822 NetSend(gUsrPwdErr[2][errheq], kROOTD_ERR);
04823 else
04824 NetSend(kErrBadPasswd, kROOTD_ERR);
04825 ErrorInfo("RpdUser: rndm tag mis-match"
04826 " (%s vs %s) - Failure",&passwd[plen-10],ctag);
04827 delete[] passwd;
04828 return auth;
04829 }
04830
04831
04832 plen -= 10;
04833 passwd[plen] = 0;
04834
04835 } else {
04836
04837 if (gClientProtocol > 11)
04838 NetSend(gUsrPwdErr[2][errheq], kROOTD_ERR);
04839 else
04840 NetSend(kErrBadPasswd, kROOTD_ERR);
04841 ErrorInfo("RpdUser: rndm tag missing or incomplete"
04842 " (pw length: %d) - Failure", plen);
04843 delete[] passwd;
04844 return auth;
04845 }
04846 }
04847
04848
04849
04850 if (gSaltRequired && lenS) {
04851 if (strncmp(passwd,salt,lenS))
04852 gSaltRequired = 0;
04853 }
04854
04855 } else {
04856
04857
04858 passwd = new char[strlen(recvbuf) + 1];
04859
04860
04861 int i, n = strlen(recvbuf);
04862 for (i = 0; i < n; i++)
04863 passwd[i] = ~recvbuf[i];
04864 passwd[i] = '\0';
04865
04866 if (gDebug > 2 && gAnon)
04867 ErrorInfo("RpdUser: received anonymous pass: '%s'", passwd);
04868 }
04869
04870
04871 auth = RpdPass(passwd,errheq);
04872
04873
04874 passwd = (char *)rpdmemset((volatile void *)passwd,0,lpwd);
04875 delete[] passwd;
04876
04877 return auth;
04878 }
04879
04880
04881 int RpdGuessClientProt(const char *buf, EMessageTypes kind)
04882 {
04883
04884
04885
04886 if (gDebug > 2)
04887 ErrorInfo("RpdGuessClientProt: Enter: buf: '%s', kind: %d", buf,
04888 (int) kind);
04889
04890
04891 int proto = 9;
04892
04893
04894 if (kind == kROOTD_USER) {
04895 char usr[64], rest[256];
04896 int ns = sscanf(buf, "%63s %255s", usr, rest);
04897 if (ns == 1)
04898 proto = 8;
04899 }
04900
04901 if (kind == kROOTD_SRPUSER) {
04902 char usr[64], rest[256];
04903 int ns = sscanf(buf, "%63s %255s", usr, rest);
04904 if (ns == 1)
04905 proto = 8;
04906 }
04907
04908 if (kind == kROOTD_KRB5) {
04909 if (strlen(buf) == 0)
04910 proto = 8;
04911 }
04912
04913 if (gDebug > 2)
04914 ErrorInfo("RpdGuessClientProt: guess for gClientProtocol is %d",
04915 proto);
04916
04917
04918 return proto;
04919 }
04920
04921
04922 char *RpdGetRandString(int Opt, int Len)
04923 {
04924
04925
04926
04927
04928
04929
04930
04931
04932 int iimx[4][4] = { { 0x0, 0xffffff08, 0xafffffff, 0x2ffffffe },
04933 { 0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe },
04934 { 0x0, 0x3ff0000, 0x7e, 0x7e },
04935 { 0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe }
04936 };
04937
04938 const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
04939
04940
04941 if (Opt < 0 || Opt > 3) {
04942 Opt = 0;
04943 if (gDebug > 2)
04944 ErrorInfo("RpdGetRandString: Unknown option: %d : assume 0", Opt);
04945 }
04946 if (gDebug > 2)
04947 ErrorInfo("RpdGetRandString: Enter ... Len: %d %s", Len, cOpt[Opt]);
04948
04949
04950 char *buf = new char[Len + 1];
04951
04952
04953 if (!gRandInit)
04954 RpdInitRand();
04955
04956
04957 int k = 0;
04958 int i, j, l, m, frnd;
04959 while (k < Len) {
04960 frnd = rpd_rand();
04961 for (m = 7; m < 32; m += 7) {
04962 i = 0x7F & (frnd >> m);
04963 j = i / 32;
04964 l = i - j * 32;
04965 if ((iimx[Opt][j] & (1 << l))) {
04966 buf[k] = i;
04967 k++;
04968 }
04969 if (k == Len)
04970 break;
04971 }
04972 }
04973
04974
04975 buf[Len] = 0;
04976 if (gDebug > 2)
04977 ErrorInfo("RpdGetRandString: got '%s' ", buf);
04978
04979 return buf;
04980 }
04981
04982
04983 int RpdGetRSAKeys(const char *pubkey, int Opt)
04984 {
04985
04986
04987 char str[kMAXPATHLEN] = { 0 };
04988 int keytype = 0;
04989
04990 if (gDebug > 2)
04991 ErrorInfo("RpdGetRSAKeys: enter: string len: %d, opt %d ",
04992 gPubKeyLen, Opt);
04993
04994 if (!pubkey)
04995 return keytype;
04996
04997 char *theKey = 0;
04998 FILE *fKey = 0;
04999
05000 if (Opt == 1) {
05001
05002
05003 fKey = fopen(pubkey, "r");
05004 if (!fKey) {
05005 if (GetErrno() == EACCES) {
05006 struct passwd *pw = getpwuid(getuid());
05007 char *usr = 0;
05008 if (pw)
05009 usr = pw->pw_name;
05010 ErrorInfo("RpdGetRSAKeys: access to key file %s denied"
05011 " to user: %s", pubkey, (usr ? usr : (char *)"????"));
05012 } else
05013 ErrorInfo("RpdGetRSAKeys: cannot open key file"
05014 " %s (errno: %d)", pubkey, GetErrno());
05015 return 0;
05016 }
05017
05018 struct stat st;
05019 if (fstat(fileno(fKey), &st) == -1) {
05020 ErrorInfo("RpdGetRSAKeys: cannot stat descriptor %d"
05021 " %s (errno: %d)", fileno(fKey), GetErrno());
05022 fclose(fKey);
05023 return 0;
05024 }
05025 if (!S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) ||
05026 (st.st_mode & 0777) != (S_IRUSR | S_IWUSR)) {
05027 ErrorInfo("RpdGetRSAKeys: key file %s: wrong permissions"
05028 " 0%o (should be 0600)", pubkey, (st.st_mode & 0777));
05029 fclose(fKey);
05030 return 0;
05031 }
05032 gPubKeyLen = fread((void *)str,1,sizeof(str),fKey);
05033 if (gDebug > 2)
05034 ErrorInfo("RpdGetRSAKeys: length of the read key: %d",gPubKeyLen);
05035
05036
05037 theKey = str;
05038 } else {
05039
05040 theKey = (char *)pubkey;
05041 }
05042
05043 if (gPubKeyLen > 0) {
05044
05045
05046 int k = 0;
05047 while (theKey[k] == 32) k++;
05048
05049 keytype = gRSAKey;
05050
05051
05052 char *pd1 = 0, *pd2 = 0, *pd3 = 0;
05053 pd1 = strstr(theKey, "#");
05054 if (pd1) pd2 = strstr(pd1 + 1, "#");
05055 if (pd2) pd3 = strstr(pd2 + 1, "#");
05056 if (keytype == 1) {
05057 if (!pd1 || !pd2 || !pd3) {
05058 if (gDebug > 0)
05059 ErrorInfo("RpdGetRSAKeys: bad format for keytype %d"
05060 " - exit", keytype);
05061 keytype = 0;
05062 }
05063 }
05064 if (keytype == 1) {
05065
05066 if (gDebug > 2)
05067 ErrorInfo("RpdGetRSAKeys: keytype %d ", keytype);
05068
05069
05070 int l1 = (int) (pd2 - pd1 - 1);
05071 char *n_exp_RSA = new char[l1 + 1];
05072 strncpy(n_exp_RSA, pd1 + 1, l1);
05073 n_exp_RSA[l1] = 0;
05074 if (gDebug > 2)
05075 ErrorInfo("RpdGetRSAKeys: got %d bytes for n_exp_RSA",
05076 strlen(n_exp_RSA));
05077
05078 int l2 = (int) (pd3 - pd2 - 1);
05079 char *d_exp_RSA = new char[l2 + 1];
05080 strncpy(d_exp_RSA, pd2 + 1, l2);
05081 d_exp_RSA[l2] = 0;
05082 if (gDebug > 2)
05083 ErrorInfo("RpdGetRSAKeys: got %d bytes for d_exp_RSA",
05084 strlen(d_exp_RSA));
05085
05086 rsa_num_sget(&gRSA_n, n_exp_RSA);
05087 rsa_num_sget(&gRSA_d, d_exp_RSA);
05088
05089 delete[] n_exp_RSA;
05090 delete[] d_exp_RSA;
05091
05092 } else if (keytype == 2){
05093
05094 #ifdef R__SSL
05095
05096 if (gDebug > 2)
05097 ErrorInfo("RpdGetRSAKeys: keytype %d ", keytype);
05098
05099
05100 BF_set_key(&gBFKey, gPubKeyLen, (const unsigned char *)theKey);
05101 #else
05102 if (gDebug > 0) {
05103 ErrorInfo("RpdGetRSAKeys: not compiled with SSL support:"
05104 " you should not have got here!");
05105 }
05106 #endif
05107 }
05108 }
05109
05110 if (fKey)
05111 fclose(fKey);
05112
05113 return keytype;
05114 }
05115
05116
05117 int RpdSavePubKey(const char *PubKey, int OffSet, char *user)
05118 {
05119
05120
05121
05122
05123
05124
05125 int retval = 0;
05126
05127 if (gRSAKey == 0 || OffSet < 0)
05128 return 1;
05129
05130 std::string pukfile = gRpdKeyRoot;
05131 pukfile.append(ItoA(OffSet));
05132
05133
05134 if (unlink(pukfile.c_str()) == -1) {
05135 if (GetErrno() != ENOENT)
05136
05137 return 2;
05138 }
05139
05140
05141 int ipuk = -1;
05142 ipuk = open(pukfile.c_str(), O_WRONLY | O_CREAT, 0600);
05143 if (ipuk == -1) {
05144 ErrorInfo("RpdSavePubKey: cannot open file %s (errno: %d)",
05145 pukfile.c_str(),GetErrno());
05146 if (GetErrno() == ENOENT)
05147 return 2;
05148 else
05149 return 1;
05150 }
05151
05152
05153 if (getuid() == 0) {
05154 struct passwd *pw = getpwnam(user);
05155 if (pw) {
05156 if (fchown(ipuk,pw->pw_uid,pw->pw_gid) == -1) {
05157 ErrorInfo("RpdSavePubKey: cannot change ownership"
05158 " of %s (errno: %d)",pukfile.c_str(),GetErrno());
05159 retval = 1;
05160 }
05161 } else {
05162 ErrorInfo("RpdSavePubKey: getpwnam failure (errno: %d)",GetErrno());
05163 retval = 1;
05164 }
05165 }
05166
05167
05168 if (retval == 0) {
05169 while (write(ipuk, PubKey, gPubKeyLen) < 0 && GetErrno() == EINTR)
05170 ResetErrno();
05171 }
05172
05173
05174 close(ipuk);
05175
05176
05177 return retval;
05178 }
05179
05180
05181 int RpdSecureSend(char *str)
05182 {
05183
05184
05185
05186
05187 char buftmp[kMAXSECBUF];
05188 char buflen[20];
05189
05190 int slen = strlen(str) + 1;
05191
05192 int ttmp = 0;
05193 int nsen = -1;
05194
05195 if (gRSAKey == 1) {
05196 strncpy(buftmp, str, slen);
05197 buftmp[slen] = 0;
05198 ttmp = rsa_encode(buftmp, slen, gRSA_n, gRSA_d);
05199 } else if (gRSAKey == 2) {
05200 #ifdef R__SSL
05201 ttmp = strlen(str);
05202 if ((ttmp % 8) > 0)
05203 ttmp = ((ttmp + 8)/8) * 8;
05204 unsigned char iv[8];
05205 memset((void *)&iv[0],0,8);
05206 BF_cbc_encrypt((const unsigned char *)str, (unsigned char *)buftmp,
05207 strlen(str), &gBFKey, iv, BF_ENCRYPT);
05208 #else
05209 ErrorInfo("RpdSecureSend: Not compiled with SSL support:"
05210 " you should not have got here! - return");
05211 #endif
05212 } else {
05213 ErrorInfo("RpdSecureSend: Unknown key option (%d) - return",
05214 gRSAKey);
05215 }
05216
05217
05218 SPrintf(buflen, 20, "%d", ttmp);
05219 NetSend(buflen, kROOTD_ENCRYPT);
05220 nsen = NetSendRaw(buftmp, ttmp);
05221 if (gDebug > 4)
05222 ErrorInfo("RpdSecureSend: sent %d bytes (expected: %d) - keytype: %d",
05223 nsen, ttmp, gRSAKey);
05224
05225 return nsen;
05226 }
05227
05228
05229 int RpdSecureRecv(char **str)
05230 {
05231
05232
05233
05234 char buftmp[kMAXSECBUF];
05235 char buflen[20];
05236
05237 int nrec = -1;
05238
05239 if (!str)
05240 return nrec;
05241
05242 if (gDebug > 2)
05243 ErrorInfo("RpdSecureRecv: enter ... (key is %d)", gRSAKey);
05244
05245 EMessageTypes kind;
05246 NetRecv(buflen, 20, kind);
05247 int len = atoi(buflen);
05248 if (gDebug > 4)
05249 ErrorInfo("RpdSecureRecv: got len '%s' %d ", buflen, len);
05250 if (!strncmp(buflen, "-1", 2))
05251 return nrec;
05252
05253
05254 nrec = NetRecvRaw(buftmp,len);
05255
05256
05257 if (gRSAKey == 1) {
05258 rsa_decode(buftmp, len, gRSA_n, gRSA_d);
05259 if (gDebug > 2)
05260 ErrorInfo("RpdSecureRecv: Local: decoded string is %d bytes long",
05261 strlen(buftmp));
05262
05263
05264 *str = new char[strlen(buftmp) + 1];
05265 strlcpy(*str, buftmp, strlen(buftmp)+1);
05266 } else if (gRSAKey == 2) {
05267 #ifdef R__SSL
05268 unsigned char iv[8];
05269 memset((void *)&iv[0],0,8);
05270 *str = new char[nrec + 1];
05271 BF_cbc_encrypt((const unsigned char *)buftmp, (unsigned char *)(*str),
05272 nrec, &gBFKey, iv, BF_DECRYPT);
05273 (*str)[nrec] = '\0';
05274 #else
05275 ErrorInfo("RpdSecureRecv: Not compiled with SSL support:"
05276 " you should not have got here! - return");
05277 #endif
05278 } else {
05279 ErrorInfo("RpdSecureRecv: Unknown key option (%d) - return",
05280 gRSAKey);
05281 }
05282
05283 return nrec;
05284 }
05285
05286
05287 int RpdGenRSAKeys(int setrndinit)
05288 {
05289
05290
05291
05292
05293
05294
05295 if (gDebug > 2)
05296 ErrorInfo("RpdGenRSAKeys: enter");
05297
05298
05299 if (!gRandInit)
05300 RpdInitRand();
05301 gRandInit = setrndinit;
05302
05303 #ifdef R__NOCRYPT
05304
05305 char *rsalt = RpdGetRandString(3,8);
05306 if (rsalt) {
05307 gRndmSalt = std::string(rsalt);
05308 delete[] rsalt;
05309 } else {
05310 if (gDebug > 0)
05311 ErrorInfo("RpdGenRSAKeys: could not generate random salt");
05312 }
05313 #endif
05314
05315 #ifdef R__SSL
05316
05317 if (gDebug > 2)
05318 ErrorInfo("RpdGenRSAKeys: Generate RSA SSL keys");
05319
05320
05321 SSL_library_init();
05322
05323
05324 SSL_load_error_strings();
05325
05326
05327 OpenSSL_add_all_ciphers();
05328
05329
05330 Int_t nbits = 1024;
05331
05332
05333 Int_t pubex = 17;
05334
05335
05336 char *rbuf = RpdGetRandString(0,40);
05337 RAND_seed(rbuf,strlen(rbuf));
05338
05339
05340 gRSASSLKey = RSA_generate_key(nbits,pubex,0,0);
05341
05342
05343 BIO *bkey = BIO_new(BIO_s_mem());
05344
05345
05346 PEM_write_bio_RSAPublicKey(bkey,gRSASSLKey);
05347
05348
05349 Int_t sbuf = 2*RSA_size(gRSASSLKey);
05350 char *kbuf = new char[sbuf];
05351 BIO_read(bkey,(void *)kbuf,sbuf);
05352 BIO_free(bkey);
05353
05354
05355 gRSAPubExport[1].len = sbuf;
05356 gRSAPubExport[1].keys = new char[gRSAPubExport[1].len + 2];
05357 strncpy(gRSAPubExport[1].keys,kbuf,gRSAPubExport[1].len);
05358 gRSAPubExport[1].keys[gRSAPubExport[1].len-1] = '\0';
05359 delete[] kbuf;
05360 if (gDebug > 2)
05361 ErrorInfo("RpdGenRSAKeys: SSL: export pub:\n%.*s",
05362 gRSAPubExport[1].len,gRSAPubExport[1].keys);
05363
05364
05365 gRSAInit = 1;
05366
05367 #endif
05368
05369
05370
05371
05372 bool notOK = 1;
05373 rsa_NUMBER p1, p2, rsa_n, rsa_e, rsa_d;
05374 int l_n = 0, l_e = 0, l_d = 0;
05375 #if R__RSADEB
05376 char buf[rsa_STRLEN];
05377 #endif
05378 char buf_n[rsa_STRLEN], buf_e[rsa_STRLEN], buf_d[rsa_STRLEN];
05379
05380 int nAttempts = 0;
05381 int thePrimeLen = kPRIMELENGTH;
05382 int thePrimeExp = kPRIMEEXP + 5;
05383 while (notOK && nAttempts < kMAXRSATRIES) {
05384
05385 nAttempts++;
05386 if (gDebug > 2 && nAttempts > 1) {
05387 ErrorInfo("RpdGenRSAKeys: retry no. %d",nAttempts);
05388 srand(rpd_rand());
05389 }
05390
05391
05392 p1 = rsa_genprim(thePrimeLen, thePrimeExp);
05393 p2 = rsa_genprim(thePrimeLen+1, thePrimeExp);
05394
05395
05396 int nPrimes = 0;
05397 while (rsa_cmp(&p1, &p2) == 0 && nPrimes < kMAXRSATRIES) {
05398 nPrimes++;
05399 if (gDebug > 2)
05400 ErrorInfo("RpdGenRSAKeys: equal primes: regenerate (%d times)",nPrimes);
05401 srand(rpd_rand());
05402 p1 = rsa_genprim(thePrimeLen, thePrimeExp);
05403 p2 = rsa_genprim(thePrimeLen+1, thePrimeExp);
05404 }
05405
05406 #if R__RSADEB
05407 if (gDebug > 2) {
05408 rsa_num_sput(&p1, buf, rsa_STRLEN);
05409 ErrorInfo("RpdGenRSAKeys: local: p1: '%s' ", buf);
05410 rsa_num_sput(&p2, buf, rsa_STRLEN);
05411 ErrorInfo("RpdGenRSAKeys: local: p2: '%s' ", buf);
05412 }
05413 #endif
05414
05415
05416 if (rsa_genrsa(p1, p2, &rsa_n, &rsa_e, &rsa_d)) {
05417 if (gDebug > 0)
05418 ErrorInfo("RpdGenRSAKeys: genrsa: attempt %d to generate"
05419 " keys failed",nAttempts);
05420 continue;
05421 }
05422
05423
05424 rsa_num_sput(&rsa_n, buf_n, rsa_STRLEN);
05425 l_n = strlen(buf_n);
05426 rsa_num_sput(&rsa_e, buf_e, rsa_STRLEN);
05427 l_e = strlen(buf_e);
05428 rsa_num_sput(&rsa_d, buf_d, rsa_STRLEN);
05429 l_d = strlen(buf_d);
05430
05431 #if R__RSADEB
05432 if (gDebug > 2) {
05433 ErrorInfo("RpdGenRSAKeys: local: n: '%s' length: %d", buf_n, l_n);
05434 ErrorInfo("RpdGenRSAKeys: local: e: '%s' length: %d", buf_e, l_e);
05435 ErrorInfo("RpdGenRSAKeys: local: d: '%s' length: %d", buf_d, l_d);
05436 }
05437 #endif
05438 if (rsa_cmp(&rsa_n, &rsa_e) <= 0)
05439 continue;
05440 if (rsa_cmp(&rsa_n, &rsa_d) <= 0)
05441 continue;
05442
05443
05444 char test[2 * rsa_STRLEN] = "ThisIsTheStringTest01203456-+/";
05445 Int_t lTes = 31;
05446 char *dumT = RpdGetRandString(0, lTes - 1);
05447 strncpy(test, dumT, lTes);
05448 delete[]dumT;
05449 char buf[2 * rsa_STRLEN];
05450 if (gDebug > 3)
05451 ErrorInfo("RpdGenRSAKeys: local: test string: '%s' ", test);
05452
05453
05454 strncpy(buf, test, lTes);
05455 buf[lTes] = 0;
05456
05457
05458 int lout = rsa_encode(buf, lTes, rsa_n, rsa_e);
05459 if (gDebug > 3)
05460 ErrorInfo("GenRSAKeys: local: length of crypted string: %d bytes", lout);
05461
05462
05463 rsa_decode(buf, lout, rsa_n, rsa_d);
05464 buf[lTes] = 0;
05465 if (gDebug > 3)
05466 ErrorInfo("RpdGenRSAKeys: local: after private/public : '%s' ", buf);
05467
05468 if (strncmp(test, buf, lTes))
05469 continue;
05470
05471
05472 strncpy(buf, test, lTes);
05473 buf[lTes] = 0;
05474
05475
05476 lout = rsa_encode(buf, lTes, rsa_n, rsa_d);
05477 if (gDebug > 3)
05478 ErrorInfo("RpdGenRSAKeys: local: length of crypted string: %d bytes ",
05479 lout);
05480
05481
05482 rsa_decode(buf, lout, rsa_n, rsa_e);
05483 buf[lTes] = 0;
05484 if (gDebug > 3)
05485 ErrorInfo("RpdGenRSAKeys: local: after public/private : '%s' ", buf);
05486
05487 if (strncmp(test, buf, lTes))
05488 continue;
05489
05490 notOK = 0;
05491 }
05492
05493 if (notOK) {
05494 ErrorInfo("RpdGenRSAKeys: unable to generate good RSA key pair"
05495 " (%d attempts)- return",kMAXRSATRIES);
05496 return 1;
05497 }
05498
05499
05500 rsa_assign(&gRSAPriKey.n, &rsa_n);
05501 rsa_assign(&gRSAPriKey.e, &rsa_e);
05502
05503
05504 rsa_assign(&gRSAPubKey.n, &rsa_n);
05505 rsa_assign(&gRSAPubKey.e, &rsa_d);
05506
05507 #if R__RSADEB
05508 if (gDebug > 2) {
05509
05510 ErrorInfo("RpdGenRSAKeys: local: generated keys are:");
05511 ErrorInfo("RpdGenRSAKeys: local: n: '%s' length: %d", buf_n, l_n);
05512 ErrorInfo("RpdGenRSAKeys: local: e: '%s' length: %d", buf_e, l_e);
05513 ErrorInfo("RpdGenRSAKeys: local: d: '%s' length: %d", buf_d, l_d);
05514 }
05515 #endif
05516
05517 gRSAPubExport[0].len = l_n + l_d + 4;
05518 if (gRSAPubExport[0].keys)
05519 delete[] gRSAPubExport[0].keys;
05520 gRSAPubExport[0].keys = new char[gRSAPubExport[0].len];
05521
05522 gRSAPubExport[0].keys[0] = '#';
05523 memcpy(gRSAPubExport[0].keys + 1, buf_n, l_n);
05524 gRSAPubExport[0].keys[l_n + 1] = '#';
05525 memcpy(gRSAPubExport[0].keys + l_n + 2, buf_d, l_d);
05526 gRSAPubExport[0].keys[l_n + l_d + 2] = '#';
05527 gRSAPubExport[0].keys[l_n + l_d + 3] = 0;
05528 #if R__RSADEB
05529 if (gDebug > 2)
05530 ErrorInfo("RpdGenRSAKeys: local: export pub: '%s'",
05531 gRSAPubExport[0].keys);
05532 #else
05533 if (gDebug > 2)
05534 ErrorInfo("RpdGenRSAKeys: local: export pub length: %d bytes",
05535 gRSAPubExport[0].len);
05536 #endif
05537
05538 gRSAInit = 1;
05539 return 0;
05540 }
05541
05542
05543 int RpdRecvClientRSAKey()
05544 {
05545
05546
05547
05548
05549
05550
05551 if (gRSAInit == 0) {
05552
05553 if (RpdGenRSAKeys(1)) {
05554 ErrorInfo("RpdRecvClientRSAKey: unable to generate local keys");
05555 return 1;
05556 }
05557 }
05558
05559
05560 int key = gRSAKey - 1;
05561 NetSend(gRSAPubExport[key].keys, gRSAPubExport[key].len, kROOTD_RSAKEY);
05562
05563
05564 EMessageTypes kind;
05565 char buflen[40];
05566 NetRecv(buflen, 20, kind);
05567 gPubKeyLen = atoi(buflen);
05568 if (gDebug > 3)
05569 ErrorInfo("RpdRecvClientRSAKey: got len '%s' %d ", buflen, gPubKeyLen);
05570
05571 int nrec = 0;
05572
05573 if (gRSAKey == 1) {
05574
05575
05576 nrec = NetRecvRaw(gPubKey, gPubKeyLen);
05577
05578 rsa_decode(gPubKey, gPubKeyLen, gRSAPriKey.n, gRSAPriKey.e);
05579 if (gDebug > 2)
05580 ErrorInfo("RpdRecvClientRSAKey: Local: decoded string is %d bytes long ",
05581 strlen(gPubKey));
05582 gPubKeyLen = strlen(gPubKey);
05583
05584 } else if (gRSAKey == 2) {
05585 #ifdef R__SSL
05586 int ndec = 0;
05587 int lcmax = RSA_size(gRSASSLKey);
05588 char btmp[kMAXSECBUF];
05589 int nr = gPubKeyLen;
05590 int kd = 0;
05591 while (nr > 0) {
05592
05593 nrec += NetRecvRaw(btmp, lcmax);
05594 if ((ndec = RSA_private_decrypt(lcmax,(unsigned char *)btmp,
05595 (unsigned char *)&gPubKey[kd],
05596 gRSASSLKey,
05597 RSA_PKCS1_PADDING)) < 0) {
05598 char cerr[120];
05599 ERR_error_string(ERR_get_error(), cerr);
05600 ErrorInfo("RpdRecvClientRSAKey: SSL: error: '%s' ",cerr);
05601 }
05602 nr -= lcmax;
05603 kd += ndec;
05604 }
05605 gPubKeyLen = kd;
05606 #else
05607 if (gDebug > 0)
05608 ErrorInfo("RpdRecvClientRSAKey: not compiled with SSL support"
05609 ": you should not have got here!");
05610 return 1;
05611 #endif
05612 } else {
05613 if (gDebug > 0)
05614 ErrorInfo("RpdRecvClientRSAKey: unknown key type (%d)", gRSAKey);
05615 }
05616
05617
05618
05619 if (RpdGetRSAKeys(gPubKey, 0) != gRSAKey) {
05620 ErrorInfo("RpdRecvClientRSAKey:"
05621 " could not import a valid key (type %d)",gRSAKey);
05622 char *elogfile = new char[gRpdKeyRoot.length() + 11];
05623 SPrintf(elogfile, gRpdKeyRoot.length() + 11, "%.*serr.XXXXXX", (int)gRpdKeyRoot.length(), gRpdKeyRoot.c_str());
05624 mode_t oldumask = umask(0700);
05625 int ielog = mkstemp(elogfile);
05626 umask(oldumask);
05627 if (ielog != -1) {
05628 char line[kMAXPATHLEN] = {0};
05629
05630 SPrintf(line,kMAXPATHLEN,
05631 " + RpdRecvClientRSAKey: error importing key\n + type: %d\n"
05632 " + length: %d\n + key: %s\n + (%d bytes were received)",
05633 gRSAKey, gPubKeyLen, gPubKey, nrec);
05634 while (write(ielog, line, strlen(line)) < 0 && GetErrno() == EINTR)
05635 ResetErrno();
05636 close (ielog);
05637 }
05638 delete [] elogfile;
05639 return 2;
05640 }
05641
05642 return 0;
05643 }
05644
05645
05646 void RpdInitRand()
05647 {
05648
05649
05650 const char *randdev = "/dev/urandom";
05651
05652 int fd;
05653 unsigned int seed;
05654 if ((fd = open(randdev, O_RDONLY)) != -1) {
05655 if (gDebug > 2)
05656 ErrorInfo("RpdInitRand: taking seed from %s", randdev);
05657 if (read(fd, &seed, sizeof(seed))) {;}
05658 close(fd);
05659 } else {
05660 if (gDebug > 2)
05661 ErrorInfo("RpdInitRand: %s not available: using time()", randdev);
05662 seed = time(0);
05663 }
05664 srand(seed);
05665 }
05666
05667
05668 int RpdAuthenticate()
05669 {
05670
05671 char buf[kMAXRECVBUF];
05672 EMessageTypes kind;
05673
05674
05675 #ifdef R__DEBUG
05676 int debug = 1;
05677 while (debug)
05678 ;
05679 #endif
05680
05681
05682
05683 int auth = 0;
05684
05685 while (!auth) {
05686
05687
05688 if (!gClientOld) {
05689 if (NetRecv(buf, kMAXRECVBUF, kind) < 0) {
05690 Error(gErr, -1, "RpdAuthenticate: error receiving message");
05691 return auth;
05692 }
05693 } else {
05694 strlcpy(buf,gBufOld, sizeof(buf));
05695 kind = gKindOld;
05696 gBufOld[0] = '\0';
05697 gClientOld = 0;
05698 }
05699
05700
05701
05702 if (gService == kROOTD && kind == kROOTD_PROTOCOL) {
05703 if (NetRecv(buf, kMAXRECVBUF, kind) < 0) {
05704 Error(gErr, -1, "RpdAuthenticate: error receiving message");
05705 return auth;
05706 }
05707 }
05708
05709
05710 gAuthProtocol = RpdGetAuthMethod(kind);
05711
05712 if (gDebug > 2) {
05713 if (kind != kROOTD_PASS) {
05714 ErrorInfo("RpdAuthenticate got: %d -- %s", kind, buf);
05715 } else {
05716 ErrorInfo("RpdAuthenticate got: %d ", kind);
05717 }
05718 }
05719
05720
05721 if (gClientProtocol == 0)
05722 gClientProtocol = RpdGuessClientProt(buf, kind);
05723
05724
05725
05726 if (gAuthProtocol != -1 && gClientProtocol > 8) {
05727
05728
05729 if (RpdCheckAuthAllow(gAuthProtocol, gOpenHost.c_str())) {
05730 if (gNumAllow>0) {
05731 if (gAuthListSent == 0) {
05732 if (gDebug > 0)
05733 ErrorInfo("Authenticate: %s method not"
05734 " accepted from host: %s",
05735 gAuthMeth[gAuthProtocol].c_str(),
05736 gOpenHost.c_str());
05737 NetSend(kErrNotAllowed, kROOTD_ERR);
05738 RpdSendAuthList();
05739 gAuthListSent = 1;
05740 goto next;
05741 } else {
05742 Error(gErr,kErrNotAllowed,"Authenticate: method not"
05743 " in the list sent to the client");
05744 return auth;
05745 }
05746 } else {
05747 Error(gErr,kErrConnectionRefused,"Authenticate:"
05748 " connection refused from host %s", gOpenHost.c_str());
05749 return auth;
05750 }
05751 }
05752
05753
05754
05755 if (kind != kROOTD_RFIO && (auth = RpdReUseAuth(buf, kind)))
05756 goto next;
05757 }
05758
05759
05760 auth = 0;
05761
05762 switch (kind) {
05763 case kROOTD_USER:
05764 auth = RpdUser(buf);
05765 break;
05766 case kROOTD_SRPUSER:
05767 auth = RpdSRPUser(buf);
05768 break;
05769 case kROOTD_PASS:
05770 auth = RpdPass(buf);
05771 break;
05772 case kROOTD_KRB5:
05773 auth = RpdKrb5Auth(buf);
05774 break;
05775 case kROOTD_GLOBUS:
05776 auth = RpdGlobusAuth(buf);
05777 break;
05778 case kROOTD_SSH:
05779 auth = RpdSshAuth(buf);
05780 break;
05781 case kROOTD_RFIO:
05782 auth = RpdRfioAuth(buf);
05783 break;
05784 case kROOTD_CLEANUP:
05785 RpdAuthCleanup(buf,1);
05786 ErrorInfo("RpdAuthenticate: authentication stuff cleaned - exit");
05787
05788 case kROOTD_BYE:
05789 RpdFreeKeys();
05790 return auth;
05791 break;
05792 default:
05793 Error(gErr,-1,"RpdAuthenticate: received bad opcode %d", kind);
05794 return auth;
05795 }
05796
05797 if (gClientProtocol > 8) {
05798
05799
05800
05801
05802
05803 int doneg = (gAuthProtocol != -1 || kind == kROOTD_PASS) &&
05804 (gRemPid > 0 || kind != kROOTD_SSH);
05805 if (gDebug > 2 && doneg)
05806 ErrorInfo("RpdAuthenticate: kind:%d meth:%d auth:%d gNumLeft:%d",
05807 kind, gAuthProtocol, auth, gNumLeft);
05808
05809
05810 if (auth == 0 && doneg) {
05811 if (gNumLeft > 0) {
05812 if (gAuthListSent == 0) {
05813 RpdSendAuthList();
05814 gAuthListSent = 1;
05815 } else
05816 NetSend(-1, kROOTD_NEGOTIA);
05817 } else {
05818 NetSend(0, kROOTD_NEGOTIA);
05819 Error(gErr, -1, "RpdAuthenticate: authentication failed");
05820 return auth;
05821 }
05822 }
05823 }
05824 next:
05825 continue;
05826 }
05827
05828 return auth;
05829 }
05830
05831 void RpdFreeKeys()
05832 {
05833
05834
05835 if (gRSAPubExport[0].keys) delete[] gRSAPubExport[0].keys;
05836 if (gRSAPubExport[1].keys) delete[] gRSAPubExport[1].keys;
05837 #ifdef R__SSL
05838 RSA_free(gRSASSLKey);
05839 #endif
05840 }
05841
05842
05843 int RpdProtocol(int ServType)
05844 {
05845
05846
05847
05848
05849
05850 int rc = 0;
05851
05852
05853 #ifdef R__DEBUG
05854 int debug = 1;
05855 while (debug)
05856 ;
05857 #endif
05858
05859 if (gDebug > 2)
05860 ErrorInfo("RpdProtocol: Enter: server type = %d", ServType);
05861
05862 int readbuf = 1;
05863 EMessageTypes kind;
05864 char proto[kMAXRECVBUF];
05865
05866
05867
05868
05869 int lbuf[2];
05870 if (NetRecvRaw(lbuf, sizeof(lbuf)) < 0) {
05871 NetSend(kErrFatal, kROOTD_ERR);
05872 ErrorInfo("RpdProtocol: error receiving message");
05873 return -1;
05874 }
05875
05876
05877
05878 kind = (EMessageTypes) ntohl(lbuf[1]);
05879 int len = ntohl(lbuf[0]);
05880 if (gDebug > 1)
05881 ErrorInfo("RpdProtocol: kind: %d %d",kind,len);
05882 if (kind == kROOTD_PROTOCOL || kind == kROOTD_CLEANUP ||
05883 kind == kROOTD_SSH) {
05884
05885 char *buf = 0;
05886 len -= sizeof(int);
05887 if (gDebug > 1)
05888 ErrorInfo("RpdProtocol: len: %d",len);
05889 if (len) {
05890 buf = new char[len];
05891 if (NetRecvRaw(buf, len) < 0) {
05892 NetSend(kErrFatal, kROOTD_ERR);
05893 ErrorInfo("RpdProtocol: error receiving message");
05894 delete[] buf;
05895 return -1;
05896 }
05897 strlcpy(proto, buf, sizeof(proto));
05898 } else {
05899
05900 proto[0] = '\0';
05901 }
05902 if (gDebug > 1)
05903 ErrorInfo("RpdProtocol: proto buff: %s", buf ? buf : "---");
05904
05905 readbuf = 0;
05906 if (buf) delete[] buf;
05907 } else if (ServType == kROOTD && kind == 0 && len == 0) {
05908
05909
05910 int llen = 12;
05911 char *buf = new char[llen];
05912 if (NetRecvRaw(buf, llen) < 0) {
05913 NetSend(kErrFatal, kROOTD_ERR);
05914 ErrorInfo("RpdProtocol: error receiving message");
05915 if (buf) delete[] buf;
05916 return -1;
05917 }
05918 if (buf) delete[] buf;
05919
05920 int type = htonl(8);
05921 if (NetSendRaw(&type,sizeof(type)) < 0) {
05922 NetSend(kErrFatal, kROOTD_ERR);
05923 ErrorInfo("RpdProtocol: error sending type to TXNetFile");
05924 return -1;
05925 }
05926
05927 llen = 4;
05928 buf = new char[llen];
05929 if (NetRecvRaw(buf,llen) < 0) {
05930 NetSend(kErrFatal, kROOTD_ERR);
05931 ErrorInfo("RpdProtocol: error receiving message");
05932 delete[] buf;
05933 return -1;
05934 }
05935 strlcpy(proto,buf, sizeof(proto));
05936 kind = kROOTD_PROTOCOL;
05937 readbuf = 0;
05938 delete[] buf;
05939 } else {
05940
05941 int size = ntohl(lbuf[1]);
05942
05943 int port;
05944 if (NetRecvRaw(&port, sizeof(int)) < 0) {
05945 NetSend(kErrFatal, kROOTD_ERR);
05946 ErrorInfo("RpdProtocol: error receiving message");
05947 return -1;
05948 }
05949 port = ntohl(port);
05950 if (gDebug > 0)
05951 ErrorInfo("RpdProtocol: port = %d, size = %d", port, size);
05952 if (size > 1)
05953 NetParOpen(port, size);
05954 }
05955
05956 int done = 0;
05957 gClientOld = 0;
05958 while (!done) {
05959
05960
05961 if (readbuf) {
05962 if (NetRecv(proto, kMAXRECVBUF, kind) < 0) {
05963 ErrorInfo("RpdProtocol: error receiving message");
05964 return -1;
05965 }
05966 }
05967 readbuf = 1;
05968
05969 switch(kind) {
05970
05971 case kROOTD_CLEANUP:
05972 RpdAuthCleanup(proto,1);
05973 ErrorInfo("RpdProtocol: authentication stuff cleaned");
05974 done = 1;
05975 rc = -2;
05976 break;
05977 case kROOTD_BYE:
05978 RpdFreeKeys();
05979 NetClose();
05980 done = 1;
05981 rc = -2;
05982 break;
05983 case kROOTD_PROTOCOL:
05984
05985 if (strlen(proto) > 0) {
05986 gClientProtocol = atoi(proto);
05987 } else {
05988 if (ServType == kROOTD) {
05989
05990
05991 if (NetSend(gServerProtocol, kROOTD_PROTOCOL) < 0) {
05992 ErrorInfo("RpdProtocol: error sending kROOTD_PROTOCOL");
05993 rc = -1;
05994 }
05995
05996 if (NetRecv(proto, kMAXRECVBUF, kind) < 0) {
05997 ErrorInfo("RpdProtocol: error receiving message");
05998 rc = -1;
05999 }
06000 if (kind != kROOTD_PROTOCOL2) {
06001 strlcpy(gBufOld, proto, sizeof(gBufOld));
06002 gKindOld = kind;
06003 gClientOld = 1;
06004 gClientProtocol = 0;
06005 } else
06006 gClientProtocol = atoi(proto);
06007 } else
06008 gClientProtocol = 0;
06009 }
06010 if (!gClientOld) {
06011
06012
06013 Int_t protoanswer = gServerProtocol;
06014 if (!gRequireAuth && gClientProtocol > 10)
06015 protoanswer += 1000;
06016
06017 if (gDebug > 0) {
06018 ErrorInfo("RpdProtocol: gClientProtocol = %d",
06019 gClientProtocol);
06020 ErrorInfo("RpdProtocol: Sending gServerProtocol = %d",
06021 protoanswer);
06022 }
06023 if (NetSend(protoanswer, kROOTD_PROTOCOL) < 0) {
06024 ErrorInfo("RpdProtocol: error sending kROOTD_PROTOCOL");
06025 rc = -1;
06026 }
06027 }
06028 done = 1;
06029 break;
06030 case kROOTD_SSH:
06031
06032 RpdSshAuth(proto);
06033 NetSend(kErrAuthNotOK, kROOTD_ERR);
06034 ErrorInfo("RpdProtocol: SSH failure notified");
06035 rc = -2;
06036 done = 1;
06037 break;
06038 default:
06039 ErrorInfo("RpdProtocol: received bad option (%d)",kind);
06040 rc = -1;
06041 done = 1;
06042 break;
06043 }
06044
06045 }
06046
06047 return rc;
06048 }
06049
06050
06051 int RpdLogin(int ServType, int auth)
06052 {
06053
06054
06055
06056 ErrorInfo("RpdLogin: enter: Server: %d, gUser: %s, auth: %d",
06057 ServType, gUser, auth);
06058
06059
06060 if (gDoLogin == 0)
06061 return -2;
06062
06063 struct passwd *pw = getpwnam(gUser);
06064
06065 if (!pw) {
06066 ErrorInfo("RpdLogin: user %s does not exist locally\n", gUser);
06067 return -1;
06068 }
06069
06070 if (getuid() == 0) {
06071
06072 #ifdef R__GLBS
06073 if (ServType == 2) {
06074
06075
06076 struct shmid_ds shm_ds;
06077 if (gShmIdCred > 0) {
06078 if (shmctl(gShmIdCred, IPC_STAT, &shm_ds) == -1) {
06079 ErrorInfo("RpdLogin: can't get info about shared memory"
06080 " segment %d (errno: %d)",gShmIdCred,GetErrno());
06081 return -1;
06082 }
06083 shm_ds.shm_perm.uid = pw->pw_uid;
06084 shm_ds.shm_perm.gid = pw->pw_gid;
06085 if (shmctl(gShmIdCred, IPC_SET, &shm_ds) == -1) {
06086 ErrorInfo("RpdLogin: can't change ownership of shared"
06087 " memory segment %d (errno: %d)",
06088 gShmIdCred,GetErrno());
06089 return -1;
06090 }
06091 }
06092 }
06093 #endif
06094
06095
06096 if (gAnon) {
06097
06098 if (chdir(pw->pw_dir) == -1) {
06099 ErrorInfo("RpdLogin: can't change directory to %s (errno: %d)",
06100 pw->pw_dir, errno);
06101 return -1;
06102 }
06103 if (chroot(pw->pw_dir) == -1) {
06104 ErrorInfo("RpdLogin: can't chroot to %s", pw->pw_dir);
06105 return -1;
06106 }
06107 }
06108
06109
06110 initgroups(gUser, pw->pw_gid);
06111
06112
06113 if (setresgid(pw->pw_gid, pw->pw_gid, 0) == -1) {
06114 ErrorInfo("RpdLogin: can't setgid for user %s", gUser);
06115 return -1;
06116 }
06117 if (setresuid(pw->pw_uid, pw->pw_uid, 0) == -1) {
06118 ErrorInfo("RpdLogin: can't setuid for user %s", gUser);
06119 return -1;
06120 }
06121 }
06122
06123 if (ServType == 2) {
06124
06125 char *home = new char[8+strlen(pw->pw_dir)];
06126 SPrintf(home, 8+strlen(pw->pw_dir), "HOME=%s", pw->pw_dir);
06127 putenv(home);
06128 }
06129
06130
06131 if (gDoLogin == 2 && !gAnon) {
06132 if (chdir(pw->pw_dir) == -1) {
06133 ErrorInfo("RpdLogin: can't change directory to %s (errno: %d)",
06134 pw->pw_dir, errno);
06135 return -1;
06136 }
06137 }
06138
06139 umask(022);
06140
06141
06142 NetSend(auth, kROOTD_AUTH);
06143
06144 if (auth == 2) NetSend(gOffSet, kROOTD_AUTH);
06145
06146 if (gDebug > 0)
06147 ErrorInfo("RpdLogin: user %s logged in", gUser);
06148
06149 return 0;
06150 }
06151
06152
06153 int RpdInitSession(int servtype, std::string &user,
06154 int &cproto, int &meth, int &type, std::string &ctoken)
06155 {
06156
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171 std::string pwd;
06172 int auth = RpdInitSession(servtype,user,cproto,meth,pwd);
06173 if (auth == 1)
06174 if (gExistingAuth)
06175 type = 1;
06176 else
06177 type = 0;
06178 else if (auth == 2)
06179 type = 2;
06180 ctoken = gCryptToken;
06181
06182 return auth;
06183 }
06184
06185 int RpdInitSession(int servtype, std::string &user,
06186 int &cproto, int &anon, std::string &passwd)
06187 {
06188
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201 if (gDebug > 2)
06202 ErrorInfo("RpdInitSession: %s", gServName[servtype].c_str());
06203
06204 int retval = 0;
06205
06206
06207 RpdInitAuth();
06208
06209
06210 NetGetRemoteHost(gOpenHost);
06211
06212 if (servtype == kPROOFD) {
06213
06214
06215 char msg[80];
06216 if (NetRecv(msg, sizeof(msg)) < 0) {
06217 ErrorInfo("RpdInitSession: Cannot receive master/slave status");
06218 return -1;
06219 }
06220
06221 retval = !strcmp(msg, "master") ? 1 : 0;
06222
06223 if (gDebug > 0)
06224 ErrorInfo("RpdInitSession: PROOF master/slave = %s", msg);
06225 }
06226
06227
06228
06229
06230
06231 int rcp = RpdProtocol(servtype);
06232 if (rcp != 0) {
06233 if (rcp == -1)
06234 ErrorInfo("RpdInitSession: error getting remote protocol");
06235 else if (rcp != -2)
06236 ErrorInfo("RpdInitSession: unknown error from RpdProtocol");
06237 return rcp;
06238 }
06239
06240
06241
06242 bool runAuth = (gClientProtocol < 11 || gRequireAuth) ? 1 : 0;
06243
06244
06245 int auth = 0;
06246 if (runAuth) {
06247 auth = RpdAuthenticate();
06248 if (auth == 0) {
06249 ErrorInfo("RpdInitSession: unsuccessful authentication attempt");
06250 return -1;
06251 }
06252 } else {
06253 auth = RpdNoAuth(servtype);
06254 }
06255
06256
06257 if (gDoLogin > 0) {
06258 if (RpdLogin(servtype,auth) != 0) {
06259 ErrorInfo("RpdInitSession: unsuccessful login attempt");
06260
06261 NetSend(0, kROOTD_AUTH);
06262 return -1;
06263 }
06264 } else {
06265
06266 NetSend(auth, kROOTD_AUTH);
06267
06268 if (auth == 2)
06269 NetSend(gOffSet, kROOTD_AUTH);
06270 if (gDebug > 0)
06271 ErrorInfo("RpdInitSession: User '%s' authenticated", gUser);
06272 retval = auth;
06273 }
06274
06275
06276 user = std::string(gUser);
06277 cproto = gClientProtocol;
06278 if (servtype == kSOCKD)
06279 anon = gSec;
06280 else
06281 anon = gAnon;
06282 if (gAnon)
06283 passwd = std::string(gPasswd);
06284
06285 return retval;
06286 }
06287
06288
06289 int RpdInitSession(int servtype, std::string &user, int &rid)
06290 {
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301 int dum1 = 0, dum2 = 0;
06302 std::string dum3;
06303 rid = gRemPid;
06304 return RpdInitSession(servtype,user,dum1,dum2,dum3);
06305
06306 }
06307
06308
06309
06310 int RpdNoAuth(int servtype)
06311 {
06312
06313
06314
06315
06316 if (gDebug > 1)
06317 ErrorInfo("RpdNoAuth: no authentication required");
06318
06319
06320 int auth = 0;
06321
06322
06323 if (servtype == kROOTD || servtype == kPROOFD) {
06324
06325 char buf[kMAXPATHLEN];
06326 EMessageTypes kind;
06327 if (NetRecv(buf, kMAXPATHLEN, kind) < 0) {
06328 NetSend(kErrBadMess, kROOTD_ERR);
06329 ErrorInfo("RpdNoAuth: error receiving target user");
06330 goto quit;
06331 }
06332
06333 if (kind == kROOTD_BYE)
06334 goto quit;
06335
06336 if (kind != kROOTD_USER) {
06337 NetSend(kErrBadOp, kROOTD_ERR);
06338 ErrorInfo("RpdNoAuth: protocol error:"
06339 " received msg type: %d, expecting: %d", kind, kROOTD_USER);
06340 goto quit;
06341 }
06342
06343
06344 char ruser[kMAXUSERLEN], user[kMAXUSERLEN];
06345 int nw = sscanf(buf,"%64s %64s",ruser,user);
06346 if (nw <= 0 || !strcmp(ruser,"-1")) {
06347 NetSend(kErrBadMess, kROOTD_ERR);
06348 ErrorInfo("RpdNoAuth: received uncorrect information: %s", buf);
06349 goto quit;
06350 }
06351
06352 if (nw == 1)
06353 snprintf(user,kMAXUSERLEN,"%s",ruser);
06354
06355 struct passwd *pw = 0;
06356 if ((pw = getpwnam(user)) == 0) {
06357 NetSend(kErrNoUser, kROOTD_ERR);
06358 ErrorInfo("RpdNoAuth: user %s unknown", user);
06359 goto quit;
06360 }
06361
06362
06363
06364 uid_t uid = getuid();
06365 if (uid && uid != pw->pw_uid) {
06366 NetSend(kErrBadUser, kROOTD_ERR);
06367 ErrorInfo("RpdNoAuth: user not same as effective user of rootd");
06368 goto quit;
06369 }
06370
06371 if (gDebug > 2)
06372 ErrorInfo("RpdNoAuth: remote user: %s, target user: %s",ruser,user);
06373
06374 SPrintf(gUser, 63, "%s", user);
06375 }
06376
06377 auth = 4;
06378
06379 quit:
06380 return auth;
06381 }
06382
06383
06384 int RpdSetUid(int uid)
06385 {
06386
06387
06388 if (gDebug > 2)
06389 ErrorInfo("RpdSetUid: enter ...uid: %d", uid);
06390
06391 struct passwd *pw = getpwuid(uid);
06392
06393 if (!pw) {
06394 ErrorInfo("RpdSetUid: uid %d does not exist locally", uid);
06395 return -1;
06396 } else if (chdir(pw->pw_dir) == -1) {
06397 ErrorInfo("RpdSetUid: can't change directory to %s", pw->pw_dir);
06398 return -1;
06399 }
06400
06401 if (getuid() == 0) {
06402
06403
06404 initgroups(pw->pw_name, pw->pw_gid);
06405
06406
06407 if (setresgid(pw->pw_gid, pw->pw_gid, 0) == -1) {
06408 ErrorInfo("RpdSetUid: can't setgid for uid %d", uid);
06409 return -1;
06410 }
06411 if (setresuid(pw->pw_uid, pw->pw_uid, 0) == -1) {
06412 ErrorInfo("RpdSetUid: can't setuid for uid %d", uid);
06413 return -1;
06414 }
06415 }
06416
06417 if (gDebug > 0)
06418 ErrorInfo("RpdSetUid: uid set (%d,%s)", uid, pw->pw_name);
06419
06420 return 0;
06421 }
06422
06423
06424 void RpdInit(EService serv, int pid, int sproto, unsigned int options,
06425 int rumsk, int sshp, const char *tmpd, const char *asrpp, int login)
06426 {
06427
06428
06429 gService = serv;
06430 gParentId = pid;
06431 gServerProtocol = sproto;
06432 gReUseAllow = rumsk;
06433 gSshdPort = sshp;
06434 gDoLogin = login;
06435
06436
06437 gCheckHostsEquiv= (bool)((options & kDMN_HOSTEQ) != 0);
06438 gRequireAuth = (bool)((options & kDMN_RQAUTH) != 0);
06439 gSysLog = (bool)((options & kDMN_SYSLOG) != 0);
06440
06441 if (tmpd && strlen(tmpd)) {
06442 gTmpDir = tmpd;
06443 gRpdAuthTab = gTmpDir + gAuthTab;
06444 gRpdKeyRoot = gTmpDir + gKeyRoot;
06445 }
06446
06447 gRpdAuthTab.append(".");
06448 gRpdAuthTab.append(ItoA(getuid()));
06449 gRpdKeyRoot.append(ItoA(getuid()));
06450 gRpdKeyRoot.append("_");
06451
06452 if (asrpp && strlen(asrpp))
06453 gAltSRPPass = asrpp;
06454
06455 #ifdef R__GLBS
06456
06457 if (RpdGlobusInit() != 0)
06458 ErrorInfo("RpdInit: failure initializing globus authentication");
06459 #endif
06460
06461 if (gDebug > 0) {
06462 ErrorInfo("RpdInit: gService= %s, gSysLog= %d, gSshdPort= %d",
06463 gServName[gService].c_str(), gSysLog, gSshdPort);
06464 ErrorInfo("RpdInit: gParentId= %d", gParentId);
06465 ErrorInfo("RpdInit: gRequireAuth= %d, gCheckHostEquiv= %d",
06466 gRequireAuth, gCheckHostsEquiv);
06467 ErrorInfo("RpdInit: gReUseAllow= 0x%x", gReUseAllow);
06468 ErrorInfo("RpdInit: gServerProtocol= %d", gServerProtocol);
06469 ErrorInfo("RpdInit: gDoLogin= %d", gDoLogin);
06470 if (tmpd)
06471 ErrorInfo("RpdInit: gTmpDir= %s", gTmpDir.c_str());
06472 if (asrpp)
06473 ErrorInfo("RpdInit: gAltSRPPass= %s", gAltSRPPass.c_str());
06474 #ifdef R__GLBS
06475 ErrorInfo("RpdInit: gHaveGlobus: %d", (int) gHaveGlobus);
06476 #endif
06477 }
06478 }
06479
06480
06481
06482 int SPrintf(char *buf, size_t size, const char *va_(fmt), ...)
06483 {
06484
06485
06486
06487
06488
06489
06490 if (!buf) {
06491 if (gDebug > 0)
06492 ErrorInfo("SPrintf: buffer not allocated: do nothing");
06493 return 0;
06494 }
06495
06496
06497 if (size < 1) {
06498 if (gDebug > 0)
06499 ErrorInfo("SPrintf: cannot determine buffer size (%d): do nothing",size);
06500 return 0;
06501 }
06502
06503
06504 va_list ap;
06505 va_start(ap,va_(fmt));
06506 int np = vsnprintf(buf, size, fmt, ap);
06507 va_end(ap);
06508
06509 if (np == -1 && gDebug > 0)
06510 ErrorInfo("SPrintf: buffer truncated (%s)",buf);
06511
06512 return np;
06513 }
06514
06515
06516
06517 char *ItoA(int i)
06518 {
06519
06520
06521
06522 const int kMAXCHR = 30;
06523 static char str[kMAXCHR];
06524
06525
06526 int nchr = (int)log10(double(i)) + 1;
06527 if (nchr > kMAXCHR)
06528 strlcpy(str,"-1", sizeof(str));
06529 else
06530 snprintf(str,30,"%d",i);
06531
06532 return str;
06533 }
06534
06535
06536 void RpdSetErrorHandler(ErrorHandler_t err, ErrorHandler_t sys, ErrorHandler_t fatal)
06537 {
06538
06539
06540 gErr = err;
06541 gErrSys = sys;
06542 gErrFatal = fatal;
06543 }
06544
06545 #ifdef R__GLBS
06546
06547 int RpdGetShmIdCred()
06548 {
06549
06550
06551 return gShmIdCred;
06552 }
06553 #endif
06554
06555
06556
06557 int RpdRetrieveSpecialPass(const char *usr, const char *fpw, char *pass, int lpwmax)
06558 {
06559
06560
06561
06562
06563
06564
06565
06566
06567
06568
06569
06570 int rc = -1;
06571 int len = 0, n = 0, fid = -1;
06572
06573
06574 if (!usr || !pass) {
06575 if (gDebug > 0)
06576 ErrorInfo("RpdRetrieveSpecialPass: invalid arguments:"
06577 " us:%p, sp:%p", usr, pass);
06578 return rc;
06579 }
06580
06581 struct passwd *pw = getpwnam(usr);
06582 if (!pw) {
06583 if (gDebug > 0)
06584 ErrorInfo("RpdRetrieveSpecialPass: user '%s' does not exist", usr);
06585 return rc;
06586 }
06587
06588
06589 int uid = pw->pw_uid;
06590 int ouid = getuid();
06591
06592
06593 if (ouid == 0) {
06594
06595
06596 if (initgroups(pw->pw_name, pw->pw_gid) == -1)
06597 ErrorInfo("RpdRetrieveSpecialPass: can't initgroups for uid %d"
06598 " (errno: %d)", uid, GetErrno());
06599
06600 if (setresgid(pw->pw_gid, pw->pw_gid, 0) == -1)
06601 ErrorInfo("RpdRetrieveSpecialPass: can't setgid for gid %d"
06602 " (errno: %d)", pw->pw_gid, GetErrno());
06603 if (setresuid(pw->pw_uid, pw->pw_uid, 0) == -1)
06604 ErrorInfo("RpdRetrieveSpecialPass: can't setuid for uid %d"
06605 " (errno: %d)", uid, GetErrno());
06606 }
06607
06608
06609 char rootdpass[kMAXPATHLEN];
06610 SPrintf(rootdpass, kMAXPATHLEN, "%s/%s", pw->pw_dir, fpw);
06611
06612 if (gDebug > 0)
06613 ErrorInfo
06614 ("RpdRetrieveSpecialPass: checking file %s for user %s",rootdpass,
06615 pw->pw_name);
06616
06617
06618 if ((fid = open(rootdpass, O_RDONLY)) == -1) {
06619 ErrorInfo("RpdRetrieveSpecialPass: cannot open password file"
06620 " %s (errno: %d)", rootdpass, GetErrno());
06621 rc = -1;
06622 goto back;
06623 }
06624
06625 struct stat st;
06626 if (fstat(fid, &st) == -1) {
06627 ErrorInfo("RpdRetrieveSpecialPass: cannot stat descriptor %d"
06628 " %s (errno: %d)", fid, GetErrno());
06629 rc = -1;
06630 goto back;
06631 }
06632 if (!S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) ||
06633 (st.st_mode & (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH)) != 0) {
06634 ErrorInfo("RpdRetrieveSpecialPass: pass file %s: wrong permissions"
06635 " 0%o (should be 0600)", rootdpass, (st.st_mode & 0777));
06636 ErrorInfo("RpdRetrieveSpecialPass: %d %d",
06637 S_ISREG(st.st_mode),S_ISDIR(st.st_mode));
06638 rc = -2;
06639 goto back;
06640 }
06641
06642 if ((n = read(fid, pass, lpwmax - 1)) <= 0) {
06643 close(fid);
06644 ErrorInfo("RpdRetrieveSpecialPass: cannot read password file"
06645 " %s (errno: %d)", rootdpass, GetErrno());
06646 rc = -1;
06647 goto back;
06648 }
06649 close(fid);
06650
06651
06652 len = n;
06653 while (len-- && (pass[len] == '\n' || pass[len] == 32))
06654 pass[len] = 0;
06655
06656
06657 pass[++len] = 0;
06658 rc = len;
06659
06660 back:
06661
06662 if (ouid == 0) {
06663
06664 if (setresgid(0, 0, 0) == -1)
06665 ErrorInfo("RpdRetrieveSpecialPass: can't re-setgid for gid 0"
06666 " (errno: %d)", GetErrno());
06667 if (setresuid(0, 0, 0) == -1)
06668 ErrorInfo("RpdRetrieveSpecialPass: can't re-setuid for uid 0"
06669 " (errno: %d)", GetErrno());
06670 }
06671
06672
06673 return rc;
06674 }
06675
06676 }