|
|
1.1 ! root 1: #include "share.h" ! 2: ! 3: file files[FILES]; /* dynamic? */ ! 4: int nfile = FILES; ! 5: int nmoffset; ! 6: ! 7: doput() ! 8: { int i; ! 9: for(i = 0; i < nfile; i++) ! 10: if(files[i].tag == client.tag) ! 11: break; ! 12: if(i >= nfile) { ! 13: error("put: tag 0x%x not found\n", client.tag); ! 14: client.errno = ENOENT; ! 15: return; ! 16: } ! 17: if(files[i].tag == roottag) /* never toss the root */ ! 18: return; ! 19: close(files[i].fd); ! 20: files[i].fd = -1; ! 21: files[i].tag = 0; ! 22: free(files[i].name); ! 23: } ! 24: ! 25: /* real paranoia would check that name and fd still refer to the same file */ ! 26: doupdate() ! 27: { int i,f = 0; ! 28: for(i = 0; i < nfile; i++) ! 29: if(files[i].tag == client.tag) ! 30: break; ! 31: if(i >= nfile) { ! 32: error("update: tag 0x%x not found\n", client.tag); ! 33: client.errno = ENOENT; ! 34: return; ! 35: } ! 36: errno = 0; ! 37: if(client.ta) ! 38: f++, client.ta += dtime; ! 39: else ! 40: client.ta = files[i].stb.st_atime; ! 41: if(client.tm) ! 42: f++, client.tm += dtime; ! 43: else ! 44: client.tm = files[i].stb.st_mtime; ! 45: if(f) /* could someone have changed the file name underfoot? */ ! 46: utime(files[i].name, &client.ta); ! 47: if(errno) { ! 48: client.errno = errno; ! 49: error("update: utime errno %d\n", errno); ! 50: /* and forget the rest of it */ ! 51: return; ! 52: } ! 53: if(client.mode != files[i].stb.st_mode) { ! 54: if(!isowner(&files[i].stb)) { ! 55: /* except for client root, this should never happen */ ! 56: error("doupdate: client user %d not owner of %s (chmod)\n", ! 57: client.uid, files[i].name); ! 58: client.errno = EPERM; ! 59: return; ! 60: } ! 61: if(cray == 1) { /* stupid thing has no fchmod */ ! 62: chmod(files[i].name, client.mode); ! 63: if(errno) { ! 64: error("chmod(%s,0%o) failed %d\n", files[i].name, ! 65: client.mode, errno); ! 66: return; ! 67: } ! 68: } else { ! 69: fchmod(files[i].fd, client.mode); ! 70: if(errno) { ! 71: error("fchmod(%s,0%o) failed %d\n", files[i].name, ! 72: client.mode, errno); ! 73: return; ! 74: } ! 75: } ! 76: } ! 77: /* refresh the stat? */ ! 78: } ! 79: ! 80: doread() ! 81: { int i, n; ! 82: for(i = 0; i < nfile; i++) ! 83: if(client.tag == files[i].tag) ! 84: break; ! 85: if(i >= nfile) { ! 86: error("doread: tag 0x%x missing\n", client.tag); ! 87: client.errno = ENOENT; ! 88: return; ! 89: } ! 90: /* permissions check missing here */ ! 91: /* trust the client, except for unknown users, and our policy on `other' */ ! 92: /*if(clientuid() == -1 && !otherok) { ! 93: client.errno = EPERM; ! 94: return; ! 95: }*/ /*no point, can't get here */ ! 96: /* if we're doing read-ahead, here's the spot */ ! 97: if((files[i].stb.st_mode & S_IFMT) == S_IFDIR) { ! 98: /* fancy directory handling would go here ! 99: doreaddir(i); ! 100: return;*/ ! 101: } ! 102: /* now we know that the headers for sndread add up to 16 bytes */ ! 103: if(files[i].pos != client.offset) { ! 104: lseek(files[i].fd, client.offset, 0); ! 105: files[i].pos = client.offset; /* are you sure? */ ! 106: } ! 107: if(16 + client.count > inlen) /* sanity */ ! 108: client.count = inlen - 16; ! 109: n = read(files[i].fd, inbuf + 16, (int)client.count); ! 110: if(n < 0) { ! 111: files[i].pos = (unsigned int)-1; /* can't trust it? */ ! 112: client.errno = errno; ! 113: return; ! 114: } ! 115: client.resplen = 16 + n; /* read sets it */ ! 116: files[i].pos += n; ! 117: } ! 118: ! 119: dowrite(p) ! 120: unsigned char *p; ! 121: { int i, n; ! 122: for(i = 0; i < nfile; i++) ! 123: if(client.tag == files[i].tag) ! 124: break; ! 125: if(i >= nfile) { ! 126: debug("dowrite: tag 0x%x missing\n", client.tag); ! 127: client.errno = ENOENT; ! 128: return; ! 129: } ! 130: /*if(clientuid() == -1 && !otherok) { ! 131: client.errno = EPERM; ! 132: return; ! 133: }*/ /* no point, can't happen */ ! 134: if(files[i].flags) { ! 135: client.errno = EPERM; ! 136: return; ! 137: } ! 138: if(files[i].pos != client.offset) { ! 139: lseek(files[i].fd, client.offset, 0); ! 140: files[i].pos = client.offset; ! 141: } ! 142: if(24 + client.count > inlen) { ! 143: client.errno = EFAULT; ! 144: return; ! 145: } ! 146: n = write(files[i].fd, inbuf + 24, (int)client.count); /* secret 24 */ ! 147: if(n != client.count) { ! 148: client.errno = errno? errno: EIO; ! 149: files[i].pos = (unsigned int) -1; /* ??? */ ! 150: return; ! 151: } ! 152: files[i].pos += i; ! 153: } ! 154: ! 155: donami(p, len) ! 156: unsigned char *p; ! 157: { int i, offset; ! 158: unsigned char *s, *t, *bufend; ! 159: for(i = 0; i < nfile; i++) ! 160: if(client.tag == files[i].tag) ! 161: break; ! 162: if(i >= nfile) { ! 163: error("nami: tag 0x%x not found\n", client.tag); ! 164: client.errno = ENOENT; ! 165: return; ! 166: } ! 167: debug("nbnami: tag 0x%x for %d\n", client.tag, i); ! 168: /* build the new name in nmbuf */ ! 169: for(s = nmbuf, t = files[i].name; *t; ) ! 170: *s++ = *t++; ! 171: *s++ = '/'; ! 172: nmoffset = s - nmbuf; ! 173: bufend = s + len; ! 174: for(t = p; *t && s < bufend; t++) { /* two tests for paranoia */ ! 175: if(s >= nmbuf + inlen) { ! 176: fatal("nami overran nmbuf\n"); ! 177: client.errno = EFAULT; ! 178: return; ! 179: } ! 180: *s++ = *t; ! 181: } ! 182: *s = 0; ! 183: debug("nbnami: nmbuf |%s|\n", nmbuf); ! 184: /* first write the simple code and then worry about . and .. and null */ ! 185: if(client.flags == 0) { ! 186: openit(); ! 187: return; ! 188: } ! 189: switch(client.flags) { ! 190: default: ! 191: error("nami: unk flag %d\n", client.flags); ! 192: client.errno = EINVAL; ! 193: return; ! 194: case NI_NXCREAT: /* expects it not to exist */ ! 195: creatit(); ! 196: break; ! 197: case NI_LINK: /* expects it not to exist */ ! 198: linkit(); ! 199: break; ! 200: case NI_MKDIR: /* expects it not to exist */ ! 201: mkdirit(); ! 202: break; ! 203: case NI_RMDIR: /* expects it to exist */ ! 204: rmdirit(); ! 205: break; ! 206: case NI_DEL: /* expects it to exist */ ! 207: delit(); ! 208: break; ! 209: case NI_CREAT: /* doesn't care */ ! 210: creatit(); ! 211: break; ! 212: } ! 213: } ! 214: ! 215: /* are fd and name consistent? (when might they not be?) */ ! 216: /* this is only called on fstat() or stats of the root */ ! 217: dostat() ! 218: { static int t = 0; ! 219: int i, n; ! 220: struct stat *x; ! 221: if(++t % 3 == 1 || t < 3) { ! 222: i = time(0) - client.ta; ! 223: /* if(i != dtime) ! 224: error("client time %d host time %d dtime %d\n", ! 225: client.ta, time(0), i); ! 226: */ ! 227: dtime = i; ! 228: } ! 229: for(i = 0; i < nfile; i++) ! 230: if(client.tag == files[i].tag) ! 231: break; ! 232: if(i >= nfile) { ! 233: error("dostat: tag %d not found\n", client.tag); ! 234: client.errno = ENOENT; ! 235: return; ! 236: } ! 237: n = fstat(files[i].fd, &files[i].stb); ! 238: if(n < 0) { /* this is probably a serious error */ ! 239: error("dostat: returned errno %d %s(%d) %x\n", errno, files[i].name, ! 240: files[i].fd, files[i].tag); ! 241: client.errno = errno; ! 242: return; ! 243: } ! 244: x = &files[i].stb; ! 245: client.ino = x->st_ino; ! 246: client.dev = hostdev(x->st_dev); ! 247: client.nlink = x->st_nlink; ! 248: client.uid = hostuid(x->st_uid); ! 249: client.gid = hostgid(x->st_gid); ! 250: client.mode = x->st_mode; /* permission calculation? */ ! 251: client.size = x->st_size; ! 252: client.ta = x->st_atime - dtime; ! 253: client.tm = x->st_mtime - dtime; ! 254: client.tc = x->st_ctime - dtime; ! 255: if(cray && client.size >= 0x80000000) ! 256: client.size = 0x7fffffff; ! 257: if((client.mode & S_IFMT) != S_IFREG && (client.mode & S_IFMT) != S_IFDIR) ! 258: client.mode = 0; ! 259: } ! 260: ! 261: /* paranoia suggests checking that fd and name are consistent */ ! 262: dotrunc() ! 263: { int i, n; ! 264: for(i = 0; i < nfile; i++) ! 265: if(client.tag == files[i].tag) ! 266: break; ! 267: if(i >= nfile) { ! 268: error("trunc: tag %d not found\n", client.tag); ! 269: client.errno = ENOENT; ! 270: return; ! 271: } ! 272: if(clientuid() == -1 && !otherok) { ! 273: client.errno = EPERM; ! 274: return; ! 275: } ! 276: n = creat(files[i].name, files[i].stb.st_mode); ! 277: if(n < 0) { ! 278: error("dotrunc: creat errno %d %s\n", errno, files[i].name); ! 279: client.errno = errno; ! 280: return; ! 281: } ! 282: close(n); ! 283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.