hid-1.4.3/Version: 1.4.3 March 1995 Ever been up at 3am on Monday morning trying to move an essential application from one piece of hardware to another and been unable to do it because you'll need a new licence key from your vendor and they don't give them out at weird hours? Well, here's a solution that works in many cases. Basically it allows you to modify the value returned by gethostid/sysinfo for the hostid on Solaris 1.x and 2.3 See the file INSTRUCTIONS for more details than provided here. Note that there are examples which show how to load system calls via modload into running kernels on Sun OS 4.1.x and 5.3/5.4. This kit contains scripts/programs to do this using four different approaches. These are (pretty much in the order of severity and danger): 1. Use shared libraries to modify the value returned by gethostid/sysinfo for a particular group of dynamically linked executables. Does not work for statically linked executables. newhostid, sidump.c (Solaris 1.x and 2.3), sysinfo.c (Solaris 2.3 & later) newhostid was contributed by Jean-Louis Faraut 2. Modify the in-core image of the kernel so that all processes on a running Solaris system will see a different hostid via gethostid/sysinfo. hid.c, hid_solaris2.c (Solaris 1.1 and 2.3), sethostid-simple-4.1, sethostid-simple-5.3 3. Build a new kernel on which certain processes running on a Solaris 1.x system will see a different hostid which can be set by a new system call (well, really just the old sethostid system call) hostid-by-egid (Solaris 1.1 only). Contributed by someone who wishes to remain anonymous hostid-by-egid-modload - dynamically loadable version of the above. Basically, it lets you load the new sethostid system call without completely rebuilding your kernel. Based on the above contribution. hostid-by-egid-solaris2 - version of this for Solaris 2.3 As an aside these might be useful to someone because they show how to dynamically load new system calls into the kernel on Solaris 1.1 and 2.3. 4. Reprogram your NVRAM so that you really have changed your hostid. nvram.c (Solaris 1.x only), nvram.info (instructions for reprogramming from the monitor) nvram-sol2.c (solaris 2.4) The other approaches just fake your OS into reporting a different hostid via the standard system calls. This approach is much more dangerous, but you may have to resort to it if your licence manager actually goes and fetches the IDPROM value (perhaps through the OPENPROM interface, see getobphostid.c for a way of doing this). In particular 1 and 2 can be undone very easily (reboot). Approach 3 can be undone by rebooting with one's old kernel. The NVRAM modifier if it is abused or malfunctions can actually render your machine unbootable, even from CDROM. Read the comments in nvram.c and nvram.info before trying this. I don't generally recommend it. ------------------------------------ Version 1.4 will include facilities for also spoofing the IP address and hostname of a system on a program by program basis. At this point I can't commit to availability; but I'll announce it in comp.sys.sun.admin when it is ready. ------------------------------------ I'll try and maintain a copy of the latest version of this package on ftp.netcom.com:/pub/he/henderso Please don't use these program to steal software or to violate your licence agreements with software vendors. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor or when your NVRAM gets wiped out by some unfortunate accident. USE AT YOUR OWN RISK. nvram.c and nvram-sol2.c are particularly dangerous. Read the comments and proceed with extreme caution. If this program malfunctions or is misused you can get your NVRAM into a state where you will no longer be able to boot Sun OS. Unless you absolutely need to modify your NVRAM, I recommend going with the approach in hid/hid_solaris2. Reprogramming your NVRAM can be useful when it gets wiped out for some reason. BE SURE TO WRITE DOWN YOUR NVRAM INFO BEFORE YOU MODIFY IT. Finally, if you want to communicate with me regarding this package, and have privacy concerns, you can send me PGP encrypted messages. I'd also really appreciate receiving any bug reports, encrypted or not. Here's my public key: -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.7 mQCPAivJ3w4AAAEEAMyer3mwrEAfnY65s17lbIzDKEJBJX5m1rceauKEMM5A41+L kUvNzdGvvaTxYgvlgQS5u7Q4Iv96BvTJUJHKUTxp+ueZjrZX5glY+T1JVQWSvlph pJ5QWr4o90de/S4GOpYdKo8JFLfGymzUDTqtm1qxT4KJb+G97eI11LPFgBXjABEB AAG0Jk1hcmsgQy4gSGVuZGVyc29uIDxtYXJraEB3aW1zZXkuYmMuY2E+iQBFAgUQ LUwfpi4uv5+/eaLVAQHRDwF/esVjxWAUgDs9A2ATwggbH3cSa+XRq5z3lfnUV+Ws UuF8lVXg3rwt99JmvGpc7oeRiQCVAgUQLUhKSuULSAGiySfVAQFFvwQAobXItWUp W+b6GxyLm+yPNNx39MAA9/gqQDbCDiCWHkzN6oVF36uDdEIyIPY9GkpDoucfRzD5 1J1ZYNu5IPa8olvcDpRNe8+WjMhGDw/qgkMFhQUepzsPaUF/7zXnZcLMFIhxY+/9 Jh1chCl+1ABJps/NhlKm6qFk+wgjShuzeFaJAJQCBRAtEatyrXg6KCkPNT0BAVPT A/dLK1yBmDhYaUcH7ZDWfo29+M9sN+tq1Woq0Ys9tLzoi72LCGrLGTOnQnx2Dvq6 6PMCQ/neu6efY+YWLVOIbiOqjXrF6VAdPi9T+EFJwLDx5S5THgPWtbwzOft7yAPs HBGZ3Qbc79mg/kj00nx9fHuwNdxMWb51NwkgTC9QqJr1iQCVAgUQK8nffeI11LPF gBXjAQHOpgP9F67ES+2iWyEEj3JU/k8lT2GAYmxrp2GiZ5yGgFFsMPDob5ZVLK+f 695hcgA6E4218FS/p+BiJlYcjyWazOl1U7g0HB0DvYcKi5s0PF+M8b+0tuD83Hb9 1ygePMmlgHe1+B5w4E1LJtnqcqlhAcLqdz/ZJ31qAVnFUppEALTx2gA= =VLrB -----END PGP PUBLIC KEY BLOCK----- Mark Henderson -- NEW FEATURES -- nvram-sol2.c new to 1.3.5 spoof-solaris (2.4) new to 1.4.0 spoof-solaris2 (1.1) new to 1.4.0 sysinfo.c - new to 1.4.1 (thanks to an anonymous contributor) dloverlay.c - new to 1.4.3 contributed by bf078@cleveland.Freenet.Edu (Brian S Walden) spoof-solaris and spoof-solaris2 allow you to spoof hostname, hostid, and IP address in much the same way as hostid. rt of the author. Please don't use these program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor or when your NVRAM gets wiped out by some unfortunate accident. Please send bug reports to Mark Henderson ---------------------------------------------------------------------- I've included several programs which do different things. All other than the nvram modifiers nvram.c (nvram_old.c) essentially spoof the operating system into believing the system has different hostid than it really does. Basically I'll break them down as follows: 1. hid.c, hid_solaris2.c, sethostid-simple-4.1, sethostid-simple-5.3 These modify the kernel so that a different hostid is returned by gethostid and sysinfo. The first two (hid.c, hid_solaris2.c) just patch a few bytes into the kernel to achieve the desired effect. sethostid-simple-4.1 and sethostid-simple-5.3 add a sethostid system call to the kernel which takes one parameter (the desired hostid). Limitations: 1. All processes on the system will report the same hostid. 2. Clever programs can figure out that the kernel is reporting a "fake" hostid. There are a couple of ways of validating this. Two I know are: Solaris 2.3 only - look at _idprom in the kernel Solaris 1.1 and 2.3 - use the openprom interface to get the idprom property. (q.v. getobphostid.c) 2. hostid-by-egid-solaris2, hostid-by-egid-modload, hostid-by-egid, run These modify the kernel so that a different hostid is returned by gethostid and sysinfo if the process is a member of certain groups or has egid in this set of groups. This allows you to have multiple hostids on a single machine. For instance process A which is in group 900, might see hostid 0x23000000 and process B in group 901 might see hostid 0x80000000 run.c is a simple program which executes a command with a group added to its membership list. Limitations: as with the above clever programs can try and defeat you. 3. newhostid, sidump.c, sysinfo.c, sidump_old.c, newhostid.old These spoof hostid using the LD_PRELOAD environment variable. Allows a system to appear to have multiple hostids. You don't even need to have root access to do this. Limitations: 1. as with the above clever programs can try and defeat you. 2. only works for dynamically linked executables. 4. nvram.c, nvram_old.c, nvram.info, nvram-sol2.c Instructions and software to modify the hostid in NVRAM for sun4m, sun4c. Really allows you to modify your hostid. Limitations: - You need to be very careful with this. In particular, you can't just change your hostid to an arbitary value. Read the instructions carefully. One comment about clever programs. You can often defeat the extended hostid checking they might do. In particular you can spoof the openprom ioctl interface with these techniques by writing a wrapper around the system ioctl. Applicability: 4.1.x 4.1.x 5.3/5.4 Notes sun3 sun4 sun4 getobphostid.c X X X hid.c X hid_solaris2.c X hostid-by-egid X X hostid-by-egid-modload X X hostid-by-egid-solaris2 X newhostid X X nvram.c,chenet.c X X sun3x, sun4c, sun4m only nvram-sol2.c X only tested under 2.4, sun4c/m nvram.info X X X run X X X for use with egid stuff sethostid-simple-4.1 X X sethostid-simple-5.3 X sidump.c X X sysinfo.c X dloverlay.c X X hostid/date and more --- Now for some detailed instructions. ---------------------------------------------------------------------- hid.c (Solaris 1.x only) - change hostid reported by Solaris 1.x/SUN OS 4.1.x gethostid 1. compile hid.c e.g. cc -o hid hid.c 2. run hid with your desired hostid and it will output a script to stdout that will change the value reported by gethostid e.g. for hostid b0b1fb0b (hex) ./hid b0b1fb0b >script.sh sh script.sh Unless your system security is terrible, you will have to run script.sh as root. or simply (as root) ./hid b0b1fb0b | sh 3. Rebooting will undo this change, if you want to make it permanent, you have two options a. just place the script output by hid in your /etc/rc.local file the script will look something like: #!/bin/sh # this script sets the hostid to b0b1bb0b adb -w -k /vmunix /dev/mem <script.sh sh script.sh Unless your system security is terrible, you will have to run script.sh as root. or simply (as root) ./hid b0b1fb0b | sh 3. Rebooting will undo the change. If you want to make it "permanent", i.e. have this new hostid every time your reboot, put the output from hid in one of the system startup files. ---------------------------------------------------------------------- sidump.c (Solaris 2.3/1.x) modify hostid reported by gethostid and sysinfo for Solaris 2.3 dynamically linked non-setuid/setgid binaries. You do not need to be root for this. new for 0.8.8 - you can override the desired hostid on a per process basis by setting the environment variable HID to the desired hostid in hex - as usual - with no leading 0x e.g. export HID=fedc1234 (ksh) setenv HID "fedc1234" (csh) Instructions: Solaris 1.x 1. compile this program cc -o sidump sidump.c (or use gcc) 2. run it with the desired hostid as the first parameter and save the output in a file with the extension .c ./sidump b0b1fb0b >foo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -assert pure-text -o foo.so OR cc -PIC -c foo.c ld foo.o -assert pure-text -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program here's a sample session feral> cc -o sidump sidump.c feral> ./sidump b0b1fb0b >foo.c feral> cc -PIC -c foo.c feral> ld -assert pure-text foo.o -o foo.so feral> export LD_PRELOAD=$PWD/foo.so feral> lmhostid feral> lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "b0b1fb0b" feral> export HID=72000000 feral> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "72000000" -------------- Solaris 2.x 1. compile this program gcc -DSOLARIS2 -o sidump sidump.c 2. run it with the desired hostid as the first parameter and save the output in a file with the extension .c ./sidump b0b1fb0b >foo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -G -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program here's a sample session: ratatosk> gcc -o sidump sidump.c ratatosk> ./sidump b0b1fb0b >foo.c ratatosk> gcc -fpic -c foo.c ratatosk> ld foo.o -G -o foo.so ratatosk> export LD_PRELOAD=$PWD/foo.so ratatosk> hostid b0b1fb0b ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "b0b1fb0b" ratatosk> export HID=72000000 ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "72000000" -- To undo this just unset LD_PRELOAD. This only effects processes for which LD_PRELOAD points to the object you create. ---------------------------------------------------------------------- sysinfo.c (Solaris 2.3 & later) modify hostid reported by gethostid and sysinfo for Solaris 2.3 dynamically linked non-setuid/setgid binaries. You do not need to be root for this. the major advantage of sysinfo.c over sidump is that a single copy of the shared library can be used on any machine of the same CPU type (SPARC or Intel). this is done without invoking the compiler and linker each time, as newhostid does, while providing complete sysinfo() emulation, like sidump. Instructions: Solaris 2.x 1. make sysinfo.o from sysinfo.c gcc -O2 -fpic -c sysinfo.c cc -O2 -pic -c sysinfo.c ld sysinfo.o -G -o sysinfo.so 2. export LD_PRELOAD=$PWD/sysinfo.so (ksh) setenv LD_PRELOAD $PWD/sysinfo.so (csh) 2. export SI_HW_SERIAL=1234567890 (ksh) setenv SI_HW_SERIAL 1234567890 (csh) 4. run the desired program here's a sample session: ratatosk> gcc -fpic -c sysinfo.c ratatosk> ld sysinfo.o -G -o sysinfo.so -ldl -lc ratatosk> export LD_PRELOAD=$PWD/sysinfo.so ratatosk> export SI_HW_SERIAL=3237998146 ratatosk> hostid c0ffee42 ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "c0ffee42" -- To undo this just unset LD_PRELOAD or SI_HW_SERIAL. This only affects processes for which LD_PRELOAD points to the object you create and for which SI_HW_SERIAL is set. --------------------------------------------------------------------- newhostid - Solaris 2.3 and Solaris 1.1 Again only for dynamically linked non setuid/setgid binaries. Run a single command "with a different hostid" Simply type newhostid Base10Hostid command [args] e.g. for hostid 72000000 (Hex) type newhostid 1912602624 command arg1 arg2 arg3 ... An older version for Solaris 1.1 only is also provided in newhostid.old the syntax for this one is slightly different, just newhostid 72000000 command arg1 arg2 arg3 ... to run command with hostid 72000000 (all in hex) --------------------------------------------------------------------- nvram.c get/change hostid in NVRAM -- Solaris 1.1 and Sun4c or Sun4m only This program is still experimental. Dangerous and tricky stuff. If you are unwilling to experiment and clean up after disasters don't use it. USE AT YOUR OWN RISK. If this program malfunctions or it is misused, you can get your Sun into a state where it will not boot, even from CDROM. In particular, you should avoid changing the most significant byte of your hostid which identifies your system type on many Sun models. 1. Read the complete instructions before you proceed. You should probably also read nvram.c 2. compile nvram cc -o nvram nvram.c 2a. If you aren't already root, become root 3. Run nvram without any parameters. If it fails with some bizarre error message, then your architecture is not supported. If you don't mind hacking the kernel you can probably hack in support for your architecture. If you send me mods I'll fold them in to the distribution. It should suggest a few adb commands to execute to make a kernel modification. 4. Run nvram again without any parameters. It just prints out the hostid and hw ethernet address. Check this against the arp tables on another machine or against the information displayed on boot. If it is not correct, do not proceed with the next step. 5. now you can try and modify the hostid by running nvram with the desired hostid as the second parameter (without 0x) e.g. nvram b0b1fb0b 6. reboot (and cross your fingers). --------------------------------------------------------------------- nvram-sol2.c get/change hostid in NVRAM -- Solaris 2.4 only (68/11) This program is still experimental. Dangerous and tricky stuff. If you are unwilling to experiment and clean up after disasters don't use it. USE AT YOUR OWN RISK. If this program malfunctions or it is misused, you can get your Sun into a state where it will not boot, even from CDROM. In particular, you should avoid changing the most significant byte of your hostid which identifies your system type on many Sun models. 1. Read the complete instructions before you proceed. You should probably also read nvram-sol2.c 2. compile nvram /opt/SUNWspro/bin/cc -o nvram-sol2 nvram-sol2.c -lelf 2a. If you aren't already root, become root 2b. If you are running a sun4c machine skip to step 3. If you are running a sun4m machine, go to a sun4c machine running Solaris 2.4 and grab the file /kernel/drv/eeprom (and put it in /kernel/drv/eeprom on the new machine). Alternatively you can get the eeprom module by mounting your Solaris 2.4 distribution media and grabbing the file /cdrom_root_dir/export/exec/kvm/sparc.sun4c.Solaris_2.4/kernel/drv/eeprom now go back to your sun4m machine and execute the following mknod /dev/eeprom c 68 11 /usr/sbin/modload /kernel/drv/eeprom (obviously I can't distribute the Sun eeprom module, but it is included by default on sun4c machine and not on sun4m machines. The driver included with the sun4c installation of Solaris 2.4 is smart enough to deal with the differences between the two machines) 3. Run nvram-sol2 without any parameters. If it fails with some bizarre error message, then your architecture or OS is not supported. If you don't mind hacking the kernel you can probably hack in support for your architecture. If you send me mods I'll fold them in to the distribution. It should suggest a few adb commands to execute to make a kernel modification. It may also suggest that you need to load the eeprom module, in which case you should do so and repeat this step. 4. Run nvram-sol2 again without any parameters. It just prints out the hostid and hw ethernet address. Check this against the arp tables on another machine or against the information displayed on boot. If it is not correct, do not proceed with the next step. 5. now you can try and modify the hostid by running nvram with the desired hostid as the second parameter (without 0x) e.g. nvram-sol2 b0b1fb0b 6. reboot (and cross your fingers). --------------------------------------------------------------------- hostid-by-egid see hostid-by-egid/README. I've only tested this on a Sparc LX running Solaris 1.1C --------------------------------------------------------------------- hostid-by-egid-modload This is similar to hostid-by-egid but you don't have to go off and completely recompile your kernel. It loads a new system call using modload. You can restore your system state with modunload. see hostid-by-egid-modload/README. I've only tested this on a Sparc LX running Solaris 1.1C --------------------------------------------------------------------- hostid-by-egid-solaris2 Version of hostid-by-egid-modload for Solaris 2.3/2.4 see hostid-by-egid-solaris2/README. --------------------------------------------------------------------- spoof-solaris, spoof-solaris2 spoof-solaris and spoof-solaris2 are modified versions of hostid-by-egid-modload and hostid-by-egid-solaris2 which also allow you to spoof the hostname. There are also instructions for spoofing the IP address (using ifconfig with Solaris 2, or a package called vip with Solaris 1.1) see the README files --------------------------------------------------------------------- sethostid-simple-4.1, sethostid-simple-5.3 see README files. run is a convenience program which will run a command with a group id in the range 900,...,909 added to its group list. For use with the hostid-by-egid stuff. Works with both Solaris 1.1 and 2.3/4. --------------------------------------------------------------------- nvram.info - this gives some information on modifying the NVRAM from the Openprom monitor. --------------------------------------------------------------------- run/run.c is useful with the hostid-by-egid* modules. see run/README for details --------------------------------------------------------------------- dloverlay.c see the comments. Another hack to use LD_PRELOAD to override various system calls (includes hostid, date, hostname etc.) contributed by Brian S. Walden or which LD_PRELOAD points to the object you create. ---------------------------------------------------------------------- sysinfo.c (Solaris 2.3 & later) modify hostid reported by gethostid and sysinfo for Solaris 2.3 dynamically linked non-setuid/setgid binaries. You do not need to be root for this. the major advantage of sysinfo.c over sidump is that a single copy of the shared library can be used on any machine of the same CPU typhid-1.4.3/chenet.cd if it doesn't spit out anything sensible. 3. now run chenet to actually modify the NVRAM e.g. chenet 08 00 20 fd fe fd Placed in the public domain by the author - 1 July 1994 only tested on some sun4m architecture and sun4c architecture machines. The kernel patches will be different for Sun4 and I don't have one to play with. If your particular machine is not supported, you may be able to hack support for the machine into this program. This program is still experimental. Dangerous and tricky stuff. If you are unwilling to experiment and clean up after disasters don't use it. USE AT YOUR OWN RISK. If this program malfunctions or it is misused, you can get your Sun into a state where it will not boot, even from CDROM. */ #define OFFSET1 017730 /* for Sun 4m, Sun OS 4.1.3 */ #define OFFSET2 03730 /* for Sun 4c, SUN OS 4.1.1 */ #define SANITY_CHECK /* don't turn this off unless you need to. If this fails it generally means that the program won't work and very well may be destructive */ /* #define TEST /* doesn't actually do mods if TEST is defined */ unsigned char buf[17]; /* larger than it needs to be */ /* offset table -- in ascending order of magnitude */ off_t offtab[2] = { OFFSET2, OFFSET1 }; #define nofftab (sizeof(offtab) / sizeof(off_t)) off_t offset; struct nlist nl[] = { "_mmeeprom" }; void check_eeprom_driver() { int kmem; off_t where; unsigned int kbuf[12]; if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/kmem\n"); exit(1); } if (nlist("/vmunix", nl) < 0) { fprintf(stderr, "cannot read namelist out of /vmunix\n"); exit(1); } if ((where = nl[0].n_value) == 0) { fprintf(stderr, "unknown kernel variable _mmeeprom\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (lseek(kmem, where, SEEK_SET) == (-1)) { fprintf(stderr, "lseek on /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (read(kmem, (char *)&kbuf[0], 48) < 48) { fprintf(stderr, "read from /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } close(kmem); if (kbuf[1] == 0x80a6a7d8 && kbuf[10] == 0x80a6a7d8) { fprintf(stderr, "please execute the following:\n"); fprintf(stderr, "adb -w -k /vmunix /dev/mem < 0xff) { fprintf(stderr, "usage: %s [xx xx xx xx xx xx]\n",argv[0]); fprintf(stderr, " e.g. %s [8 0 20 7 19 4d]\n", argv[0]); exit(1); } } } else { fprintf(stderr, "usage: %s [xx xx xx xx xx xx]\n",argv[0]); fprintf(stderr, " e.g. %s [8 0 20 7 19 4d]\n", argv[0]); exit(1); } check_eeprom_driver(); /* note: if you know what you are doing you might want to comment this line out. */ if (read_enet) { if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for read\n"); exit(1); } } else { #ifdef TEST if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for read\n"); exit(1); } #else if ((fd = open("/dev/eeprom", O_RDWR)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for write\n"); exit(1); } #endif } offset = 0xffffffff; /* dummy value */ for (j = 0; j < nofftab; j++) { if (lseek(fd,offtab[j],SEEK_SET) < 0) { fprintf(stderr, "lseek failed for %o\n", offtab[j]); continue; } if (read(fd,buf,16) < 16) { fprintf(stderr, "read of /dev/eeprom failed for %o\n", offtab[j]); continue; } #ifdef TEST for (i=0; i<16; i++) printf("%02x ", buf[i]); printf("\n"); #endif /* this will fail if you have modified the value returned by gethostid by using one of the other programs in this package. In that case I wouldn't disable this check, but restore your old gethostid behaviour or replace the gethostid call in this code with a reference to your "real" hostid. If your architecture is weird this should detect the problem and not try and write into places we shouldn't. (remember the AT YOUR OWN RISK comment). */ for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; if ((acc != buf[15]) || (buf[1] != (hid_reported_by_gethostid >> 24) ) || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff)) || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff)) || (buf[14] != (hid_reported_by_gethostid &0xff))) { continue; } offset = offtab[j]; break; } if (offset == 0xffffffff) { fprintf(stderr, "perhaps you have a weird kernel -- failed\n"); exit(1); } printf("current hostid = %02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]); printf("enetaddr = %02x:%02x:%02x:%02x:%02x:%02x\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); if (!read_enet) { if (lseek(fd,offset,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } for (i=0; i<6; i++) buf[i+2] = (unsigned char) new[i]; for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; buf[15] = acc & 0xff; #ifndef TEST if (write(fd,buf,16) < 16) { fprintf(stderr, "write failed\n"); } #else for (i=0; i<16; i++) printf("%02x ", buf[i]); printf("\n"); #endif fprintf(stderr, "now please execute the following command\n"); fprintf(stderr, "/usr/etc/eeprom 'diag-switch?=false'\n"); } close(fd); } fails it generally means that the program won't work and very well may be destructive */ /* #define TEST /* doesn't actually do mods if TEST is definedhid-1.4.3/getobphostid.c in NVRAM, so the name is misleading * * define SOLARIS2 if you are compiling for SOLARIS2 * define TEST to include the very simple test driver * define DEBUG to produce copious output - including the complete idprom * contents according to openprom * * Of course, you need read permission to /dev/openprom to do this. It * appears that the default configuration on Solaris 1.x gives everyone * read permission, but on Solaris 2.3 you need to be root or in group * sys. */ #include #include #if defined(TEST) || defined(DEBUG) #include #endif #ifdef SOLARIS2 #include #define bzero(a,b) memset((a),0,(b)) #else #include #endif /* * getobphostid - gets hostid according to the openprom driver * returns 0 on failure */ unsigned int getobphostid() { struct opio { unsigned int size; unsigned char arr[OPROMMAXPARAM]; } foo; int fd,done = 0; #ifdef DEBUG int i; #endif if ((fd = open("/dev/openprom", O_RDONLY)) < 0) { #ifdef DEBUG perror("cannot open /dev/openprom"); #endif return (0); } foo.size = OPROMMAXPARAM; bzero(&foo.arr[0],OPROMMAXPARAM); if (ioctl(fd, OPROMNEXT, &foo) < 0) { #ifdef DEBUG perror("ioctl failed (OPROMNEXT)"); #endif return(0); } foo.size = OPROMMAXPARAM; bzero(&foo.arr[0],OPROMMAXPARAM); for (;!done;) { foo.size = OPROMMAXPARAM; if (ioctl(fd, OPROMNXTPROP, &foo) < 0) { #ifdef DEBUG perror("ioctl failed (OPROMNXTPROP)"); #endif return(0); } if (foo.size == 0) /* not on list ! */ return 0; if (strncmp(&foo.arr[0], "idprom", 6)) continue; #ifdef DEBUG printf("%s: ", &foo.arr[0]); #endif strcpy(&foo.arr[0],&foo.arr[0]); foo.size=OPROMMAXPARAM; if (ioctl(fd, OPROMGETPROP, &foo) < 0) { #ifdef DEBUG perror("ioctl failed (OPROMGETPROP)"); #endif return(0); } #ifdef DEBUG for (i=0;i main(argc,argv) int argc; char *argv[]; { unsigned int hid; unsigned int hi; unsigned int low; if (argc != 2) { fprintf(stderr, "usage: %s hostid\n",argv[0]); fprintf(stderr, " e.g. %s b0b1fb0b\n", argv[0]); exit(1); } sscanf(argv[1],"%08x",&hid); hi = (hid & 0xfffffc00) >> 10; printf("#!/bin/sh\n"); printf("# this script sets the hostid to %08x\n",hid); printf("adb -w -k /vmunix /dev/mem < main(argc,argv) int argc; char *argv[]; { unsigned int hid; int i; char obuf[15]; for (i=0; i<15; i++) obuf[i] = '\0'; if (argc != 2) { fprintf(stderr, "usage: %s hostid\n",argv[0]); exit(1); } sscanf(argv[1],"%08x",&hid); sprintf(obuf,"%u", hid); /* should this be %010u ? */ printf("#!/bin/sh\n"); printf("# this script sets the hostid to %08x\n",hid); printf("adb -w -k /kernel/unix /dev/mem < main(argc,argv) int argc; char *argv[]; { unsigned int hid; unsigned int hi; unsigned int low; if (argc != 2) { fprintfhid-1.4.3/hostid-by-egid-modload/d 0 72000000 which should modify the hostid for processes with gid 900. You can remove the sethostid call by using modunload. You can check whether or not it is currently installed with modstat. This package check running process's effective gid and user's gid to determine which hostid should be returned. If the gid is between 900 to 909, the specified hostid will be returned. Otherwise, the original hostid will be returned. Therefore, you can setgid the target checking excutable file and it will get what you want when the gethostid system call is called. For example, we run '/bin/sethostid 0 12345678'. All running processes with gid 900 will get hostid as 12345678 rather than the real hostid. Remember the hostid above are all hexadecimal values. N.B. sethostid.exec must be executable. Depending upon where you got the distribution you might have to chmod +x it. see ../run for a small utility for use with this. int i; char obuf[15]; for (i=0; i<15; i++) obuf[i] = '\0'; if (argc != 2) { fprintf(stderr, "usage: %s hostid\n",argv[0]); exit(1); } sscanf(argv[1],"%08x",&hid); sprintf(obuf,"%u"hid-1.4.3/hostid-by-egid-modload/kern_hostid.cf they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include #include #define NHOSTID 10 static unsigned hostid[NHOSTID]={0}; int sethostid(); static struct sysent sethostid_sysent = { 2, sethostid } ; static struct vdlsys vd = { VDMAGIC_SYS, /* magic number */ "sethostid", /* name */ 0, /* syscall number (filled in automagically) */ &sethostid_sysent /* description of syscall */ }; Gethostid() { unsigned machineid; u_short gid; int i; gethostid(); machineid = u.u_r.r_val1; gid = u.u_gid; if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } u.u_r.r_val1 = machineid; return; } sethostid(uap) register struct a { int n; unsigned hostid; } *uap; { if (!suser()) { u.u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { u.u_error = EINVAL; return; } u.u_r.r_val1 = hostid[uap->n] = uap->hostid; u.u_error = 0; return; } sethostidinit(function_code, vdp, vdi, vds) unsigned int function_code; struct vddrv *vdp; addr_t vdi; struct vdstat *vds; { switch (function_code) { case VDLOAD: vdp->vdd_vdtab = (struct vdlinkage *)&vd; sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = Gethostid; return 0; case VDUNLOAD: sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = gethostid; return 0; case VDSTAT: return 0; default: return EIO; } } dlsys vd = { VDMAGIC_Shid-1.4.3/hostid-by-egid-modload/makefilestid.c clean: rm -f core *.o sethostid kern_hostid sethostid.h .u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { u.u_error = EINVAL; return; } u.u_r.r_val1 = hostid[uap->n] = uap->hostid; u.u_error = 0; return; } sethohid-1.4.3/hostid-by-egid-modload/sethostid.cs program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); sscanf(argv[2], "%x", &hostid); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); if (syscall(SYS_sethostid, n, hostid)==-1) { perror(argv[0]); exit(1); } } unsigned machineid; u_short gid; int i; gethostid(); machineid = u.u_r.r_val1; gid = u.u_gid; if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTIhid-1.4.3/hostid-by-egid-modload/sethostid.execbility or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has thid-1.4.3/hostid-by-egid/76 5625177304 11067be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. -- Most commericial packages are bounded to machine hostid for protection. This ID is built in PROM on Sun Sparc machine. The purpose of this program is to let you specify the hostid freely and you can run the commericial programs on another machine with differnet machine hostid. This package is tested and works fine on SunOS 4.1.2, 4.1.3 and 4.1.3_U1. INSTALLATION: step 1. Copy kern_hostid.c into /sys/os step 2. Add the following line in /sys/conf.common/files.cmn os/kern_hostid.c standard step 3. Replace gethostid declartion with Gethostid, and add the new declartion of sethostid. Change system call 143 into sethostid. The modified version of /sys/os/init_sysent.c should contain the following lines. line 25: int Gethostid(),sethostname(),gethostname(),getpid(); line 32: int sethostid(); line 362: 2, Gethostid, /* 142 = gethostid */ 2, sethostid, /* 143 = old sethostid */ step 4: Configure your own kernel and rebuild it. Install it in /vmunix and reboot. step 5: Compile sethostid.c and install sethostid in /bin. step 6: Done. USAGE: This package check running process's effective gid and user's gid to determine which hostid should be returned. If the gid is between 900 to 909, the specified hostid will be returned. Otherwise, the original hostid will be returned. Therefore, you can setgid the target checking excutable file and it will get what you want when the gethostid system call is called. For example, we run '/bin/sethostid 0 12345678'. All running processes with gid 900 will get hostid as 12345678 rather than the real hostid. Remember the hostid above are all heximal value. If you have any problem, try to see the source code. No help is provided. see ../run for a small utility for use with this. ved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. -- Most commericial packages are bounded to machine hostid for protection. This ID is built in PROM on Sun Sparc machine. The purpose of this program is to let you specihid-1.4.3/hostid-by-egid/kern_hostid.cll be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #define NHOSTID 10 static unsigned hostid[NHOSTID]={0}; Gethostid() { unsigned machineid; u_short gid; int i; gethostid(); machineid = u.u_r.r_val1; gid = u.u_gid; if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } u.u_r.r_val1 = machineid; return; } sethostid(uap) register struct a { int n; unsigned hostid; } *uap; { if (!suser()) { u.u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { /* small change - markh */ u.u_error = EINVAL; return; } u.u_r.r_val1 = hostid[uap->n] = uap->hostid; u.u_error = 0; return; } stid, /* 142 = gethostid */ 2, sethostid, /* 143 = old sethostid */ step 4: Configure your own kernel and rebuild it. Install it in /vmunix and reboot. step 5: Compile sethostid.c and install sethostid in /bin. step 6: Done. USAGE: This package check running process's effective gid and uhid-1.4.3/hostid-by-egid/sethostid.ctuations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); sscanf(argv[2], "%x", &hostid); if (syscall(143, n, hostid)==-1) { perror(argv[0]); exit(1); } } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } u.u_r.r_val1 = machineid; return; } sethostid(uap) register struct a { int n; unsigned hostid; } *uap; { if (!suser()) { u.u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0))hid-1.4.3/newhostidsk. The author disclaims responsibility for # any damages that might result from the use of this program, even # if they result from negligence on the part of the author. # # Also, please don't use this program to steal software. The intended # use is for emergency situations where an application has to be moved from # one computer to another (e.g. in the event of a hardware malfunction) # and licence keys cannot be obtained quickly from the vendor. Many # vendors will not supply licence keys outside of business hours. # #run a Sun dynamically linked executable with a new hostid # - notes - only works on a Sun. Only tested under Solaris 2.3 and 1.[01] # - only works with dymanically linked executables. # # SunOS 5.x code is an alpha release (not fully tested) # usage: # newhostid Base10Hostid command [args] # On Solaris 1.x (Sun OS 4.1.x) you can also # newhostid 0x72000000 command # if you want to use hex # Sun OS 5.x note: # if it turns out that you need somewhat more complete sysinfo emulation # check out sidump.c #Warning: The following file names are used by this script: #/tmp/gethostid.{c,o,so} -> if OS == SunOS 4.1.x #/tmp/sysinfo.{c,c.head,c.tail,so} -> if OS == SunOS 5.x # #modify the following line to meet your site requirement GCC=/opt/gnu/bin/gcc #only required by SunOS 5.x # if [ $# -lt 2 ] then echo 'Usage:newhostid hostid(base 10) command [args]' exit 1 fi case `/usr/bin/uname -s` in SunOS) ;; *) echo 'Only for SunOS. Sorry.' exit 1 ;; esac case `/usr/bin/uname -r` in 4.1.*) (cd /tmp cat > gethostid.c < sysinfo.c.head <> sysinfo.c.tail DOT=${DOT}. COUNT=`expr $COUNT + 1` done echo "buf[$COUNT] = 0;" >> sysinfo.c.tail cat >> sysinfo.c.tail < sysinfo.c rm sysinfo.c.head sysinfo.c.tail #debug: cat sysinfo.c $GCC -fpic -c sysinfo.c ld sysinfo.o -G -o sysinfo.so rm sysinfo.o sysinfo.c ) shift LD_PRELOAD=/tmp/sysinfo.so $* rm /tmp/sysinfo.so ;; esac rks with dymanically linked executables. # # SunOS 5.x code is an alpha release (not fully tested) # usage: # newhostid Base10Hostid command [args] # On Solaris 1.x (Sun OS 4.1.x) you can also # newhostid 0x72000000 command # if you want to use hex # Sun OS 5.x note: # if it turns out that you need somewhat more complete sysinfo emulation # check out sidump.c #Warning: The following file names are used by this script: #/tmp/gethohid-1.4.3/newhostid.oldl be useful, # but without any warranty; without even the implied warranty of # merchantability or fitness for a particular purpose. You use # this program at your own risk. The author disclaims responsibility for # any damages that might result from the use of this program, even # if they result from negligence on the part of the author. # # Also, please don't use this program to steal software. The intended # use is for emergency situations where an application has to be moved from # one computer to another (e.g. in the event of a hardware malfunction) # and licence keys cannot be obtained quickly from the vendor. Many # vendors will not supply licence keys outside of business hours. # if [ $# -lt 2 ] then echo Usage:newhostid hostid command [args] exit 1 fi (cd /tmp cat > gethostid.c < Placed in the public domain by the author - 23 June 1994 This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. Sorry about all the legal BS, but given that use of this program is dangerous and inexperienced people will use it, I don't have much choice from both an ethical and legal point of view. */ #define OFFSET1 017730 /* for Sun 4m, Sun OS 4.1.3 */ #define OFFSET2 03730 /* for Sun 4c, SUN OS 4.1.1 */ #define SANITY_CHECK /* don't turn this off unless you need to. If this fails it generally means that the program won't work and very well may be destructive */ /* #define TEST /* doesn't actually do mods if TEST is defined */ unsigned char buf[17]; /* larger than it needs to be */ /* offset table -- in ascending order of magnitude */ off_t offtab[2] = { OFFSET2, OFFSET1 }; #define nofftab (sizeof(offtab) / sizeof(off_t)) off_t offset; struct nlist nl[2]; void check_eeprom_driver() { int kmem; off_t where; unsigned int kbuf[12]; if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/kmem\n"); exit(1); } fprintf(stderr,"nvram - Mark Henderson \n"); fprintf(stderr, "Placed in the public domain by the author - 23 June 1994\n\n"); fprintf(stderr, "This program is distributed in the hope that it will be useful,\n"); fprintf(stderr, "but without any warranty; without even the implied warranty of\n"); fprintf(stderr, "merchantability or fitness for a particular purpose. You use\n"); fprintf(stderr, "this program at your own risk. The author disclaims responsibility for\n"); fprintf(stderr, "any damages that might result from the use of this program, even\n"); fprintf(stderr, "if they result from negligence on the part of the author.\n"); fprintf(stderr, "Malfunction or misuse of this program can damage your computer.\n\n"); nl[0].n_name="_mmeeprom"; nl[1].n_name = NULL; if (nlist("/vmunix", nl) < 0) { fprintf(stderr, "cannot read namelist out of /vmunix\n"); exit(1); } if ((where = nl[0].n_value) == 0) { fprintf(stderr, "unknown kernel variable _mmeeprom\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (lseek(kmem, where, SEEK_SET) == (-1)) { fprintf(stderr, "lseek on /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (read(kmem, (char *)&kbuf[0], 48) < 48) { fprintf(stderr, "read from /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } close(kmem); if (kbuf[1] == 0x80a6a7d8 && kbuf[10] == 0x80a6a7d8) { fprintf(stderr, "please execute the following:\n"); fprintf(stderr, "adb -w -k /vmunix /dev/mem <> 24) ) || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff)) || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff)) || (buf[14] != (hid_reported_by_gethostid &0xff))) { continue; } offset = offtab[j]; break; } if (offset == 0xffffffff) { fprintf(stderr, "perhaps you have a weird kernel -- failed\n"); exit(1); } printf("current hostid = %02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]); /* may as well print this out */ printf("enetaddr = %02x:%02x:%02x:%02x:%02x:%02x\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); if (!read_hostid) { if (lseek(fd,offset,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } buf[1] = hid >> 24; buf[12] = (hid >> 16) &0xff; buf[13] = (hid >> 8) &0xff; buf[14] = hid &0xff; for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; buf[15] = acc & 0xff; #ifndef TEST if (write(fd,buf,16) < 16) { fprintf(stderr, "write failed\n"); } fprintf(stderr, "gethostid now returns %08x\n", gethostid()); #else for (i=0; i<16; i++) printf("%02x ", buf[i]); printf("\n"); #endif } close(fd); } ameter (wihid-1.4.3/nvram.infose. You use this document at your own risk. The author disclaims responsibility for any damages that might result from the use of this document, even if they result from negligence or errors on the part of the author. Placed in the public domain by the author - Jan 1995 - Mark Henderson All numbers in here are in hex. At the bottom of this file, there's also some information on the Sun 3/80. Also look at the NVRAM FAQ. anon ftp from thor.ece.uc.edu:/pub/sun-faq/FAQs/eeprom-nvram.faq Here's some information on changing the NVRAM from the Forth based Sun Openprom monitor. Consider this a beta release. Eventually I'll probably submit it to the folks who put out the nvram faq, but for now this is a seperate document. Also, there is the really nice nvram FAQ which is posted to comp.sys.sun.hardware routinely. As far as I know, this is only applicable to Sun4m and Sun4c class machines. If you have a copy of the Sun Openprom manual (you can get it off the Solaris 2.3 answerbook), it might be handy to have that on hand as a reference. These steps are not the shorted path to getting this changed. Take a look at nvram.c if you are just interested in modifying your NVRAM hostid, are running Sun OS 4.1.x and don't care about the details. This information might also be useful in putting things back together if nvram.c malfunctions. Before doing anything else, write down a copy of the nvram "idprom" information. You can get it under Sun OS 4.1.x by running /usr/etc/devinfo -vp (on Solaris 2.x, /usr/sbin/prtconf -vp) or at the Openprom monitor prompt by typing the command .idprom (yes the "." is part of the command) You'll need this information if the NVRAM gets screwed up and you need to try and back out. Having it does not guarantee that you'll be able to restore it, but life will be easier if you have it. Step 1. Determine the physical address of the NVRAM (in the case of Sun4m machines I'm interested in the second page). If you're system is on this table you can probably just read it off the table and skip to step 2. addr space arch SS1,SS2,ELC,IPC 02000000 obio sun4c Sun Classic 71201000 0 sun4m Sun LX,SS5 71201000 0 sun4m Sun SS20,SS10 f1201000 f sun4m Thanks to weindlin@pcs.mot.com for supplying some of the data in this table. Hopefully this table will get larger as people send me info. If your system is not in the table, and you are running Sun OS 4.1.x, do the following (Solaris 2.4 instructions follow in Step 1b): Step 1a. (Sun OS 4.1.x) While Sun OS 4.1.x is running (and while the system is idle!!) do the following. Modify the instructions accordingly if you have some of the security features installed. hold down the L1/Stop key and type a you will get a prompt which says ok For Sun4m machines: type the command fefff000 pgmap? the output will list a physical address which might look like f.f120.1000 the part before the first dot is the address space and the rest is the actual address. This is the SS20 case from the above table. Now type go to resume Sun OS operation. -- For Sun4c machines: type the command ffff8000 pgmap? the physical address will probably list a space (in the ELC case the address space is given as I/O) and an address (again for the ELC 02000000). the monitor will want you to type in this address space as obio later. The Sun Openprom manual also gives sbus and obmem as possible address spaces. Now type go to resume Sun OS operation. -- At this point if you're really nice, you'll send me an Email message with your Sun model and physical address/address space so I can add it to my table. Indicate whether or not you want me to give credit. Unless you ask me not to, I'll credit you just below the table. -- Step 1b. (Solaris 2.4) Solaris 2.4 instructions for determining the physical address of the NVRAM. 1. make sure the eeprom driver is loaded. An easy way to do this is to cp /dev/eeprom /dev/null 2. execute /usr/sbin/prtconf -vp and look for the information on eeprom which should look something like: Node 0xffec068c name: 'eeprom' model: 'mk48t02' reg: 00000001.f2000000.00000800 address: ffd04000 (*** note this address ***) 3. hit L1-A to stop the machine 4. at the ok prompt type ffd04000 pgmap? (replace ffd04000 with the address given by prtconf) 5. you'll get output which specifies an address space and a physical address. e.g. sun4c output looks something like: Onboard I/O Physical: 2000000 ... so the address space is I/O Physical address is 2000000 6. Now type go at the ok prompt to resume Sun OS operation. -- Step 2. From this point on it doesn't matter what version of Solaris you are running. Shut down your system (e.g. with /etc/halt) -- Step 3. Make sure you wrote down your original idprom info. You can get it by typing .idprom now. Figure out what your desired hostid and ethernet address are. Note that you shouldn't change either the first hex byte of the hostid or the first three bytes of the ethernet address. Doing so can cause problems. -- Step 4. Map the physical address determined above to address 0 using the map-page command. The format of the command is:
map-page e.g. ELC 02000000 obio 0 map-page SS20 f1201000 f 0 map-page Classic 71201000 0 0 map-page -- Step 5. If you are on a Sun4c the virtual address of the idprom information is now 7d8 If you are on a Sun4m the virtual address of the idprom information is now fd8 type either 7d8 20 dump for sun4c or fd8 20 dump for sun4m as appropriate. -- Step 6. The information which starts at f/7d8 is as follows: byte contents d8 01 - version number - always 01 d9 first byte of hostid (system type) da-df 6 byte ethernet address (first three bytes are 08,00,20) e0-e3 date of manufacture. Often all 0s e4 second byte of hostid e5 third byte of hostid e6 fourth byte of hostid e7 idprom checksum - xor of contents of bytes d8-e6 Verify that the information the dump command spits out is consistent with the above. If not, DO NOT PROCEED. -- Step 7. Now you can make changes. Be very careful and be sure to recompute the checksum after making changes. If you don't, you'll get nasty warnings about an incorrect idprom checksum on boot. I'm know repeating myself, but don't change the first byte of the hostid or the first three bytes of the ethernet address. I'm told that the first byte of the hostid is used to determine the architecture when booting from CDROM on most current Sun models. If you alter the first three bytes of the ethernet address you might get message which say that you have a defective motherboard (but then I don't know of any other consequences of changing this to some _reasonable_ value, especially avoid ff:ff:ff:ff:ff:ff !) The openprom command to change a single byte is c! e.g. 44 7dd c! will change byte 7dd (virtual address) to 44. 7d8 20 dump or fd8 20 dump will give you a listing of this area of NVRAM. -- Step 8. Type reset at the ok prompt. You should then reboot with your new hostid/enet addr. --------------------------------------------------------------------- Here's a table which matches system models with the first byte of the hostid. This is from a posting to comp.sys.sun.admin by Andy.Behrens@coat.com 01 2/1x0 02 2/50 11 3/160 12 3/50 13 3/2x0 14 3/110 17 3/60 18 3/e 21 4/2x0 22 4/1x0 23 4/3x0 24 4/4x0 31 386i/150 or 386i/250 41 3/4x0 42 3/80 51 SPARCstation 1 (4/60) 52 SPARCstation IPC (4/40) 53 SPARCstation 1+ (4/65) 54 SPARCstation SLC (4/20) 55 SPARCstation 2 (4/75) 56 SPARCstation ELC (4/25) 57 SPARCstation IPX (4/50) 61 4/e 71 4/6x0 (670) 72 SPARCstation 10 80 SPARCclassic /or/ SPARC 5 --------------------------------------------------------------------- Quick steps to modify NVRAM IDPROM info on a Sun 3/80 (people have to do this because of the usual battery problem, as with the sun4c machines) All numbers in hex. Tested with version 2.9 PROMS. This may not be the most elegant procedure, but this should allow you to modify the NVRAM IDPROM info on a sun 3/80. Hit L1-A after you turn it on comment: ^t is a command. Don't try control-T. Only tested with 2.9.2 PROMS. > ^t fef04000 you'll get output which includes the following (samples included) TIA entry = 33FA500 TIB entry = 33FB80A PTE = 64000049 Write these values down!! now change the TIA entry for fedfa000 to match the above > m a fedfa000 TIA MAP FEDFA000 [...] ? 33FA500 hit control-D at next ? prompt now change the TIB entry to match the above > m b fedfa000 TIB MAP FEDFA000 [...] ? 33FB80A now change the pagemap entry to match the above > p fedfa000 PageMap FEDFA000 [...] ? 64000049 > o fedfa7d8 ... now enter new IDPROM values. You need to get the checksum right. byte contents fedfa7d8 01 - version number - always 01 fedfa7d9 first byte of hostid (system type, 42 for sun 3/80) fedfa7da-df 6 byte ethernet address (first three bytes are 08,00,20) fedfa7e0-e3 date of manufacture. Often all 0s fedfa7e4 second byte of hostid fedfa7e5 third byte of hostid fedfa7e6 fourth byte of hostid fedfa7e7 idprom checksum - xor of contents of bytes d8-e6 Note if you have SUN OS 4.1.1 booted (i.e. you're doing this for some other reason than an IDPROM with invalid data), you can just write values into fedfa7d8 ... fedfa7e7 with the o command. You don't need to do all the mapping stuff. hid-1.4.3/nvram_old.c running this will invalidate the overall NVRAM checksum. So after it make some trivial change with the eeprom command (change the baud rate on a serial port or something like that e.g. /usr/etc/eeprom diag-switch?=false ) first you need to turn off the protection in the OS to keep you from modifying /dev/eeprom locations after 017730 use adb adb -k -w /vmunix /dev/mem _mmeeprom+8/W 901223ff which changes or %o1, 0x3d8, %o1 to or %o1, 0x3ff, %o1 Unfortunately this change with adb to the eeprom device seems to depend on the exact version of Sun OS you are running. Don't assume it will work without looking around intelligently. e.g. For SUN OS 4.1.1 on a Sun 4c you need to: adb -w /vmunix /dev/mem _mmeeprom+4/W 80a6a7ff _mmeeprom+0x28/W 80a6a7ff which changes a couple of compare operations. Also be very careful. The first byte of the hostid identifies the type of system you are running. On modern Suns OS boot CDs depend on this information to get the correct architecture. If you change it you may be reduced to poking around in NVRAM from the monitor next time you have to boot from CD. Here's a mapping of what gets read into buf (at OFFSET) buf[0] = always 01? buf[1] = system id/first byte of hostid. buf[2] \ buf[3] \ buf[4] \ HW ethernet address (6 bytes) buf[5] / buf[6] / buf[7]/ buf[8],...,buf[11] = always 00? buf[12] = second byte of hostid buf[13] = third byte of hostid buf[14] = fourth byte of hostid buf[15] = checksum the checksum is buf[0] ^ buf[1] ^ ... ^ buf[14] i.e. it must be the case that the xor of buf[0] through buf[15] is 0 Without any parameters, it reports the hostid from NVRAM. Otherwise it changes it. Mark Henderson Placed in the public domain by the author - 23 June 1994 This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #define OFFSET 017730 /* for Sun 4m, Sun OS 4.1.3 */ /* #define OFFSET 03730 /* for Sun 4c, SUN OS 4.1.1 */ #define SANITY_CHECK /* don't turn this off unless you need to. If this fails it generally means that the program won't work and very well may be destructive */ #undef TEST /* doesn't actually do mods if TEST is defined */ unsigned char buf[17]; main(argc,argv) int argc; char *argv[]; { unsigned int hid; int fd; int i; unsigned int acc; int read_hostid; unsigned int hid_reported_by_gethostid = gethostid(); if (argc == 1) { /* no args - just get hostid from prom */ read_hostid = 1; } else if (argc == 2) { read_hostid = 0; sscanf(argv[1],"%08x",&hid); } else { fprintf(stderr, "usage: %s [hostid]\n",argv[0]); fprintf(stderr, " e.g. %s b0b1fb0b\n", argv[0]); exit(1); } if (read_hostid) { if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for read\n"); exit(1); } } else { #ifdef TEST if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for read\n"); exit(1); } #else if ((fd = open("/dev/eeprom", O_RDWR)) < 0) { fprintf(stderr, "cannot open /dev/eeprom for read\n"); exit(1); } #endif } if (lseek(fd,OFFSET,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } if (read_hostid) { if (read(fd,buf,16) < 16) { fprintf(stderr, "read of /dev/eeprom failed\n"); exit(1); } printf("%02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]); for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; if (acc != buf[15]) { fprintf(stderr, "warning: ID CHKSUM INVALID\n"); fprintf(stderr,"^buf = %02x\n", acc & 0xff); fprintf(stderr,"buf[15] = %02x\n", buf[15] & 0xff); } } else { #ifdef SANITY_CHECK /* this will fail if you have modified the value returned by gethostid by using one of the other programs in this package. In that case I wouldn't turn this off but restore your old gethostid behaviour or replace the gethostid call above with a reference to your "real" hostid, if your architecture is weird this should detect the problem and not try and write into places we shouldn't. */ if (read(fd,buf,16) < 16) { fprintf(stderr, "read of /dev/eeprom failed\n"); exit(1); } #ifdef TEST for (i=0; i<16; i++) printf("%02x ", buf[i]); printf("\n"); #endif for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; if ((acc != buf[15]) || (buf[1] != (hid_reported_by_gethostid >> 24) ) || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff)) || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff)) || (buf[14] != (hid_reported_by_gethostid &0xff))) { fprintf(stderr, "SANITY CHECK FAILED -- aborting\n"); fprintf(stderr, "perhaps the value of the define OFFSET is wrong\n"); exit(1); } if (lseek(fd,OFFSET,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } #endif buf[1] = hid >> 24; buf[12] = (hid >> 16) &0xff; buf[13] = (hid >> 8) &0xff; buf[14] = hid &0xff; for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; buf[15] = acc & 0xff; #ifndef TEST if (write(fd,buf,16) < 16) { fprintf(stderr, "write failed\n"); } #else for (i=0; i<16; i++) printf("%02x ", buf[i]); printf("\n"); #endif } close(fd); } ing /dev/eeprom locations after 017730 use adb adb -k -w /vmunix /dev/mem _mmeeprom+8/W 901223ff which changes or %o1, 0x3d8, %o1 to or %o1, 0x3hid-1.4.3/sidump.cndor. Many vendors will not supply licence keys outside of business hours. New feature to be included in version 1.0 of the package: 18 July 1994 the environment variable HID can be set to the desired hostid in hex. (no leading 0x, a-f lower case) In retrospect, I should have written this in perl. Instructions: Solaris 1.x 1. compile this program cc -o sidump sidump.c 2. run it with the desired hostid as the first parameter and save the output in a file with the extension .c ./sidump b0b1fb0b >foo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -assert pure-text -o foo.so OR cc -PIC -c foo.c ld foo.o -assert pure-text -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program here's a sample session feral> cc -o sidump sidump.c feral> ./sidump b0b1fb0b >foo.c feral> cc -PIC -c foo.c feral> ld -assert pure-text foo.o -o foo.so feral> export LD_PRELOAD=$PWD/foo.so feral> lmhostid feral> lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "b0b1fb0b" feral> export HID=72000000 feral> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "72000000" -------------- Solaris 2.x 1. compile this program gcc -DSOLARIS2 -o sidump sidump.c 2. run it with the desired hostid as the first parameter and save the output in a file with the extension .c ./sidump b0b1fb0b >foo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -G -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program here's a sample session: ratatosk> gcc -o sidump sidump.c ratatosk> ./sidump b0b1fb0b >foo.c ratatosk> gcc -fpic -c foo.c ratatosk> ld foo.o -G -o foo.so ratatosk> export LD_PRELOAD=$PWD/foo.so ratatosk> hostid b0b1fb0b ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "b0b1fb0b" ratatosk> export HID=72000000 ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "72000000" */ #include #ifdef SOLARIS2 #include int commands[] = {SI_HW_SERIAL, SI_SYSNAME,SI_HOSTNAME, SI_RELEASE,SI_VERSION,SI_MACHINE,SI_ARCHITECTURE,SI_HW_PROVIDER, SI_SRPC_DOMAIN}; #endif #define NCOMMANDS (sizeof(commands)/sizeof(int)) main(argc,argv) int argc; char *argv[]; { int i,j; char buf[1024]; unsigned int hostid; if (argc != 2) { fprintf(stderr, "usage: %s hostid\n", argv[0]); exit(1); } sscanf(argv[1], "%x", &hostid); printf("#include \n"); printf("#include \n"); printf("extern char **environ;\n"); printf("unsigned int xyzzy_ghid()\n"); printf("{\n"); printf(" int i,j,c; char **s; char *e;\n"); printf(" unsigned int hid;\n"); printf(" hid = 0;\n"); printf(" s = environ;\n"); printf(" for (; *s; s++) {\n"); printf(" e = *s;\n"); printf(" if (*e++ == \'H\' \n"); printf(" && (*e++ == \'I\')\n"); printf(" && (*e++ == \'D\')\n"); printf(" && (*e++ == \'=\')) {\n"); printf(" for (j=28; (*e) && j>=0; j -=4 ) {\n"); printf(" c = (-1);\n"); printf(" if (*e >= \'0\' && *e <= \'9\') \n"); printf(" c = *e - \'0\';\n"); printf(" if (*e >= \'a\' && *e <= \'f\') \n"); printf(" c = *e - \'a\' + 10;\n"); printf(" e++;\n"); printf(" if (c == (-1))\n"); printf(" break;\n"); printf(" hid = hid | (c << j);\n"); printf(" }\n"); printf(" return hid;\n"); printf(" }\n"); printf(" }\n"); printf(" return 0;\n"); printf("}\n"); printf("gethostid() { \n"); printf("unsigned x;\n"); printf("if (x=xyzzy_ghid()) \n"); printf("{return x; }"); printf("else return 0x%08x; }\n", hostid); #ifdef SOLARIS2 printf("long sysinfo(command,buf,count)\nint command;\nchar *buf;\n"); printf("long count;\n{\nchar *c = buf; int i; unsigned int x,y;\n"); printf("switch(command) { \n"); printf("case %u:\n", commands[0]); sprintf(buf,"%u",hostid); /* should this be %010u ??? */ printf("if (!(x = xyzzy_ghid())) {\n"); for (j=0; j < strlen(buf); j++) printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]); printf("if (c < (buf + count)) *c++ = 0;\n"); printf("buf[count-1] = 0;\n"); printf("}\n"); printf("else {\n"); printf("y = 1000000000;\n"); printf("for (i=0; (i<10) && (ifoo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -G -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program (Note: it actually seems enough to do the following in 3/4: gcc -c foo.c export LD_PRELOAD=$PWD/foo.o ) here's a sample session: ratatosk> gcc -o sidump sidump_old.c ratatosk> ./sidump b0b1fb0b >foo.c ratatosk> gcc -fpic -c foo.c ratatosk> ld foo.o -G -o foo.so ratatosk> export LD_PRELOAD=$PWD/foo.so ratatosk> hostid b0b1fb0b ratatosk> lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "b0b1fb0b" You could wrap this in a script for convenience (q.v. newhostid) Solaris 1.1) */ #include #include int commands[] = {SI_HW_SERIAL, SI_SYSNAME,SI_HOSTNAME, SI_RELEASE,SI_VERSION,SI_MACHINE,SI_ARCHITECTURE,SI_HW_PROVIDER, SI_SRPC_DOMAIN}; #define NCOMMANDS (sizeof(commands)/sizeof(int)) main(argc,argv) int argc; char *argv[]; { int i,j; char buf[1024]; unsigned int hostid; if (argc != 2) { fprintf(stderr, "usage: %s hostid\n", argv[0]); exit(1); } sscanf(argv[1], "%x", &hostid); printf("#include \n"); printf("gethostid() { return 0x%08x; }\n", hostid); printf("long sysinfo(command,buf,count)\nint command;\nchar *buf;\n"); printf("long count;\n{\nchar *c = buf;\n"); printf("switch(command) { \n"); printf("case %u:\n", commands[0]); sprintf(buf,"%u",hostid); for (j=0; j < strlen(buf); j++) printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]); printf("if (c < (buf + count)) *c++ = 0;\n"); printf("buf[count-1] = 0;\n"); printf("break;\n"); for (i=1; i< NCOMMANDS; i++) { sysinfo(commands[i], buf,1024); printf("case %u:\n", commands[i]); for (j=0; j < strlen(buf); j++) printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]); printf("if (c < (buf + count)) *c++ = 0;\n"); printf("buf[count-1] = 0;\n"); printf("break;\n"); } printf("default: \nreturn(-1); \n}\n"); printf("return(strlen(buf) + 1);}\n"); } if (argc != 2) { fprintf(stderr, "usage: %s hostid\n", argv[0]); exit(1); } sscanf(argv[1], "%x", &hostid); printf("#hid-1.4.3/hostid-by-egid-solaris2/eful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); hostid=strtoul(argv[2], NULL, 16); if (syscall(SYS_sethostid, n, hostid)==-1) { perror(argv[0]); exit(1); } } ed hostid as the first parameter and save the output in a file with the extension .c ./sidump b0b1fb0b >foo.c 3. make foo.o from foo.c gcc -fpic -c foo.c ld foo.o -G -o foo.so 4. export LD_PRELOAD=$PWD/foo.so (ksh) setenv LD_PRELOAD $PWD/foo.so (csh) 5. run the desired program (Note: it actually seems enough to do the following in 3/4: gcc -c foo.c export LD_PRELOAD=$PWD/foo.ohid-1.4.3/hostid-by-egid-solaris2/sethostid.cogram is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. before you install this modify /etc/name_to_sysnum to bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 14 Aug 1994 */ #include #include #include #include #include #include #include #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[16]; int sethostid(); struct sysent sethostid_sysent = {2,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "kern_hostid v1.02", &sethostid_sysent, }; extern systeminfo(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { gid = creds->cr_gid; bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if (gid >= 900 && gid < 900+NHOSTID) { if (serials[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if (serials[gid - 900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct as {int n; unsigned int hostid;}; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { return EINVAL; } numtos( (unsigned long)uap->hostid, &serials[uap->n][0]); foo->r_val1 = uap->hostid; return 0; } _init(void) { int i,status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; for (i=0; i < NHOSTID; i++) serials[i][0] = 0; } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } ntf("break;\n"); for (i=1; i< NCOMMANDS; i++) { sysinfo(commands[i], buf,1024); hid-1.4.3/hostid-by-egid-solaris2/makefileg sys ./sethostid /usr/sbin/install -f /usr/local/bin -m 0755 -u root -g sys ./sid clean: rm -f core *.o sid sethostid sethostid.h mod_syscallops; hid-1.4.3/hostid-by-egid-solaris2/READMEpick an unused syscall number. There is also a limit on the number you can pick, which is determined by the size of the sysent table. To find out what the limit is you can use adb adb -k /dev/ksyms /dev/mem sysentsize/D ^D # i.e. control-D You should be able to pick any unused syscall number between 1 and the number output by adb above minus 1. Alternatively just use an unused number which is less than the largest number which occurs in /etc/name_to_sysnum After modifying /etc/name_to_sysnum you must reboot for the change to take effect. 2. Look at the makefile and check that the location of the C compiler is right for your system. You do NOT want to get /usr/ucb/cc. gcc should be OK. 3. Type make load This should load the sethostid call. 4. Type make sid This makes the program that allows you to modify the hostid for a particular group. e.g. Now you can modify the hostid for group 900 to be 23000000 by typing ./sid 0 23000000 6. You can unload the system call as follows. Type /usr/sbin/modinfo You'll get output which includes a line which looks something like 76 fc42d000 621 177 1 sethostid (kern_hostid v1.0) To remove the module type /usr/sbin/modunload -i 76 Replace 76 by the first number in the line output by modinfo. 7. If you like you can install sid and sethostid by typing make install If you do this, when you reboot, the sethostid module will be automatically loaded when sethostid is called (i.e. when you run sid). see ../run for a small utility for use with this. buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct hid-1.4.3/run/ay.cd root. I recommend 4755 or 4711 for the * permissions */ #include #include #include #include #define GID_T int /* should be gid_t for Solaris 2, but it really doesn't matter */ GID_T grouplist[NGROUPS_MAX]; #define NHOSTID 10 main(argc,argv) int argc; char *argv[]; { int i,j; if (argc < 3) { fprintf(stderr, "usage: run command\n"); exit(1); } i = getgroups(NGROUPS_MAX, grouplist); #ifdef DEBUG for (j=0; j< i ; j++) fprintf(stderr, "%d\n", grouplist[j]); #endif grouplist[i] = (GID_T)(atoi(argv[1]) + 900); if (grouplist[i] < 900 || grouplist[i] >= NHOSTID + 900) { fprintf(stderr, "usage: run command\n is out of range\n"); exit(1); } if (i >= NGROUPS_MAX) { fprintf(stderr, "already in NGROUPS_MAX groups\n"); exit(1); } i = setgroups(i+1, grouplist); if (i < 0) { fprintf(stderr, "setgroups failed\n"); exit(1); } seteuid(getuid()); execvp(argv[2], argv+2); } ll as follows. Type /usr/sbin/modinfo You'll get output which includes a line which looks something like 76 fc42d000 621 177 1 sethostid (kern_hostid v1.0) To remove the module type /usr/sbinhid-1.4.3/run/READMEtall program does. I'm not an expert on writing "safe" setuid programs, so please check this out carefully before you install it. (General good instructios for any setuid root program!) An example of its use (with the solaris 2 hostid-by-egid module) is as follows: (edit /etc/name_to_sysnum as described in the documentation for hostid-by-egid-solaris2) ratatosk# cd hostid-by-egid-solaris2 ratatosk# make load /opt/SUNWspro/bin/cc -D_KERNEL -c sethostid.c ld -r -o sethostid sethostid.o /usr/sbin/modload ./sethostid ratatosk# make sid grep sethostid /etc/name_to_sysnum | sed 's/^/#define SYS_/' ratatosk#sethostid.h /opt/SUNWspro/bin/cc -o sid -I. sid.c ratatosk# ./sid 0 24000000 ratatosk# ./sid 1 25000000 ratatosk# cd ../run ratatosk# make cc -o run run.c chmod 4755 run ratatosk# hostid 80512f45 ratatosk# ./run 0 hostid 24000000 ratatosk# ./run 1 hostid 25000000 ratatosk# ./run 2 hostid 80512f45 ratatosk# ./run 0 lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "24000000" ratatosk# ./run 0 lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "25000000" ratstosk# ./run 0 csh ratatosk# hostid 24000000 ratatosk# lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "24000000" ratatosk# modinfo ... 78 fc6a50a0 a62 277 1 sethostid (kern_hostid v1.02) ... ratatosk# modunload -i 78 ratatosk# hostid 80512f45 ratatosk# ./run 0 hostid 80512f45 sethostid module will be automatically loaded when sethostid is called (i.e. when you run sid). see ../run for a small utility for use with this. buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct hid-1.4.3/sethostid-simple-4.1/ 0 5705604000 11057a new kernel. You'll find the original contribution in ../hostid-by-egid This will probably only work on versions of Sun OS later than 4.1. I've tried it on both a Sun 3 and Sun 4. to use this: make load make sethostid ./sethostid 72000000 All numbers are in hex. Do NOT put in the leading 0x. You can remove the sethostid call by using modunload. You can check whether or not it is currently installed with modstat. N.B. sethostid.exec must be executable. Depending upon where you got the distribution you might have to chmod +x it. Calling sethostid with the hostid of 0 will restore the hostid to the default. e.g. ./sethostid 0 _sysnum | sed 's/^/#define SYS_/' ratatosk#sethostid.h /opt/SUNWspro/bin/cc -o sid -I. sid.c ratatosk# ./sid 0 24000000 ratatosk# ./sid 1 25000000 ratatosk# cd ../run ratatosk# make cc -o run run.c chmod 4755 run ratatosk# hostid 80512f45 ratatosk# ./run 0 hid-1.4.3/sethostid-simple-4.1/kern_hostid.ction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include #include static unsigned hostid = 0; int sethostid(); static struct sysent sethostid_sysent = { 1, sethostid } ; static struct vdlsys vd = { VDMAGIC_SYS, /* magic number */ "sethostid", /* name */ 0, /* syscall number (filled in automagically) */ &sethostid_sysent /* description of syscall */ }; Gethostid() { gethostid(); if (hostid) u.u_r.r_val1 = hostid; u.u_error = 0; return; } sethostid(uap) register struct a { unsigned hostid; } *uap; { if (!suser()) { u.u_error = EACCES; return; } hostid = uap->hostid; u.u_r.r_val1 = hostid; u.u_error = 0; return; } sethostidinit(function_code, vdp, vdi, vds) unsigned int function_code; struct vddrv *vdp; addr_t vdi; struct vdstat *vds; { switch (function_code) { case VDLOAD: vdp->vdd_vdtab = (struct vdlinkage *)&vd; sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = Gethostid; return 0; case VDUNLOAD: sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = gethostid; return 0; case VDSTAT: return 0; default: return EIO; } } t vdlsys vd = { VDMAGIC_SYS, /* magic number */ "sethid-1.4.3/sethostid-simple-4.1/makefileLAGS = -DKERNEL ASFLAGS = -P load: kern_hostid.o chmod +x sethostid.exec /usr/etc/modload kern_hostid.o -v -entry _sethostidinit -exec sethostid.exec sethostid: sethostid.o sethostid.h cc -o sethostid -I. sethostid.c clean: rm -f core *.o sethostid kern_hostid sethostid.h unsigned hostid; } *uap; { if (!suser()) { u.u_error = EACCES; return; } hostid = uap->hostid; u.u_r.r_val1 = hostid; u.u_error = 0; return; } sethostidinit(function_code, vdp, vdihid-1.4.3/sethostid-simple-4.1/sethostid.cnf(argv[1], "%x", &hostid); if (syscall(SYS_sethostid, hostid)==-1) { perror(argv[0]); exit(1); } } ./run 2 hostid 80512f45 ratatosk# ./run 0 lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "24000000" ratatosk# ./run 0 lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this machine is "25000000" ratstosk# ./run 0 csh ratatosk# hostid 24000000 ratatosk# lmhostid lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc. The FLEXlm host ID of this mahid-1.4.3/sethostid-simple-4.1/sethostid.execor Solaris 2.3. If the module failed to load, the sysent table was often left in a bad state which would lead to a kernel panic pretty soon. - added Makefile lines to install sid in /usr/local/bin and sethostid in /kernel/sys (if one does "make install"). I'm actually beginning to appreciate Solaris 2.x; automatically loading system calls into the kernel on the fly when they are called is pretty cool. 1.2c - bug in some of the user sethostid programs (not the kernel modules) would not allow hostid > 0x7fffffff because of signed vs unsigned problems. On solaris 2.3 changes strtol to strtoul. On Solaris 1.1 changed strtol to appropriate sscanf calls. The sscanf calls are not tolerant of a leading 0x as are strtol and strtoul, but this doesn't really both me. 1.3 - minor changes to documentation 1.3.1 - added information about sun 3/80 to nvram.info 1.3.2 - fixed solaris 2 instructions. important to reboot after modifying /etc/name_to_sysnum - added a couple of systems to nvram.info - explicit path to ld added in solaris 2 makefiles (/usr/ccs/bin/ld) 1.3.3 - added nvram-sol2.c - minor change to nvram.c that should be harmless. 1.3.4 - cosmetic changes to nvram-sol2.c and nvram.c 1.3.5 - mods to nvram-sol2.c for sun4m 1.4.0 - correction to nvram.info - spoof-solaris and spoof-solaris2 released. 1.4.2 - by default sun4m installations don't include the eeprom driver. But you can get the eeprom driver from a sun4c machine and it is smart enough to work nicely. Forgot to mention this in 1.4.1. nkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].shid-1.4.3/sethostid-simple-5.3/e number you can pick, which is determined by the size of the sysent table. To find out what the limit is you can use adb adb -k /dev/ksyms /dev/mem sysentsize/D ^D # i.e. control-D You should be able to pick any unused syscall number between 1 and the number output by adb above minus 1. Alternatively just use an unused number which is less than the largest number which occurs in /etc/name_to_sysnum After modifying /etc/name_to_sysnum you must reboot for the change to take effect. 2. Look at the makefile and check that the location of the C compiler is right for your system. You do NOT want to get /usr/ucb/cc. gcc should be OK. 3. Type make load This should load the sethostid call. 4. Type make sid This makes the program that allows you to modify the hostid for a particular group. e.g. Now you can modify the hostid to be 23000000 by typing ./sid 23000000 6. You can unload the system call as follows. Type /usr/sbin/modinfo You'll get output which includes a line which looks something like 76 fc42d000 621 177 1 sethostid (kern_hostid v1.0) To remove the module type /usr/sbin/modunload -i 76 Replace 76 by the first number in the line output by modinfo. 7. If you like you can install sid and sethostid by typing make install If you do this, when you reboot, the sethostid module will be automatically loaded when sethostid is called (i.e. when you run sid). setting the hostid to 0 will restore the default. 1.3.2 - fixed solaris 2 instructions. important to reboot after modifying /etc/name_to_sysnum - added a couple of systems to nvram.info - explicit path to ld added in solaris 2 makefiles (/usr/ccs/bin/ld) 1.3.3 - added nvram-sol2.c - minor change to nvhid-1.4.3/sethostid-simple-5.3/makefilethis modify /etc/name_to_sysnum to bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 14 Aug 1994 */ #include #include #include #include #include #include #include static char serial[16]; char xyzzy_rbuf[16]; int sethostid(); struct sysent sethostid_sysent = {1,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "simple sethostid v1.0", &sethostid_sysent, }; extern systeminfo(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if (serial[0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serial[i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } foo->r_val1 = ret; return 0; } struct as {int hostid; }; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if (!uap->hostid) { serial[0] = '\0'; foo->r_val1 = 0; } else { numtos( (unsigned long)uap->hostid, &serial[0]); foo->r_val1 = uap->hostid; } return 0; } _init(void) { int status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; serial[0] = 0; } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } (c < (buf + count)) *c++ = 0;\n"); printf("buf[count-1] = 0;\n"); printf("break;\n"); } printf("default: \nreturn(-1); \n}\n"); printf("return(strlen(buf) + 1);}\n"); } if (argc != 2) { fprintf(stderr, "usage: %s hostid\n", argv[0]); exit(1); } sscanf(argv[1], "%x", &hostid); printf("#hid-1.4.3/sethostid-simple-5.3/sid.c 144 ot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; if (argc<2) { fprintf(stderr, "%s \n", argv[0]); exit(1); } hostid=strtoul(argv[1], NULL, 16); if (syscall(SYS_sethostid, hostid)==-1) { perror(argv[0]); exit(1); } } work and how the procedure works in Solaris 1.1 Mark Henderson 14 Aug 1994 */ #include #include #include #include #include #include #include static char serial[16]; char xyzzy_rbuf[16]; int sethostid(); struct sysent sethostid_sysent = {1,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys mhid-1.4.3/nvram-sol2.cJan 1995 This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. Sorry about all the legal BS, but given that use of this program is dangerous and inexperienced people will use it, I don't have much choice from both an ethical and legal point of view. */ /* * getobphostid - gets hostid according to the openprom driver * returns 0 on failure */ unsigned int getobphostid() { struct opio { unsigned int size; unsigned char arr[OPROMMAXPARAM]; } foo; int fd,done = 0; if ((fd = open("/dev/openprom", O_RDONLY)) < 0) { return (0); } foo.size = OPROMMAXPARAM; memset(&foo.arr[0],0,OPROMMAXPARAM); if (ioctl(fd, OPROMNEXT, &foo) < 0) { return(0); } foo.size = OPROMMAXPARAM; memset(&foo.arr[0],0,OPROMMAXPARAM); for (;!done;) { foo.size = OPROMMAXPARAM; if (ioctl(fd, OPROMNXTPROP, &foo) < 0) { return(0); } if (foo.size == 0) /* not on list ! */ return 0; if (strncmp(&foo.arr[0], "idprom", 6)) continue; strcpy(&foo.arr[0],&foo.arr[0]); foo.size=OPROMMAXPARAM; if (ioctl(fd, OPROMGETPROP, &foo) < 0) { return(0); } done=1; } close(fd); return ((foo.arr[1] << 24)|(foo.arr[12] << 16)|(foo.arr[13] << 8) |(foo.arr[14])); } #define OFFSET1 017730 /* for Sun 4m */ #define OFFSET2 03730 /* for Sun 4c */ /* #define TEST /* doesn't actually do mods if TEST is defined */ unsigned char buf[17]; /* larger than it needs to be */ /* offset table -- in ascending order of magnitude */ off_t offtab[2] = { OFFSET2, OFFSET1 }; #define nofftab (sizeof(offtab) / sizeof(off_t)) off_t offset; struct nlist nl[2]; unsigned int bsd_gethostid() { unsigned char buf[1024]; buf[0] = 0; sysinfo(SI_HW_SERIAL, buf, 1024); return (strtoul(buf,NULL,10)); } void check_eeprom_driver() { int kmem; off_t where; unsigned int kbuf[12]; fprintf(stderr,"nvram-sol2 - Mark Henderson \n"); fprintf(stderr, "Placed in the public domain by the author - Jan 1995\n\n"); fprintf(stderr, "This program is distributed in the hope that it will be useful,\n"); fprintf(stderr, "but without any warranty; without even the implied warranty of\n"); fprintf(stderr, "merchantability or fitness for a particular purpose. You use\n"); fprintf(stderr, "this program at your own risk. The author disclaims responsibility for\n"); fprintf(stderr, "any damages that might result from the use of this program, even\n"); fprintf(stderr, "if they result from negligence on the part of the author.\n"); fprintf(stderr, "Malfunction or misuse of this program can damage your computer.\n\n"); if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/kmem\n"); exit(1); } nl[0].n_name = "nvram"; nl[1].n_name = NULL; if (nlist("/dev/ksyms", nl) < 0) { fprintf(stderr, "cannot read namelist out of /vmunix\n"); exit(1); } if ((where = nl[0].n_value) == 0) { fprintf(stderr, "unknown kernel variable nvram\n"); fprintf(stderr, "execute the following and try again\n"); fprintf(stderr, "/usr/sbin/modload /kernel/drv/eeprom\n"); exit(1); } if (lseek(kmem, where, SEEK_SET) == (-1)) { fprintf(stderr, "lseek on /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (read(kmem, (char *)&kbuf[0], 48) < 48) { fprintf(stderr, "read from /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } close(kmem); if (kbuf[11] == 0x9422a028) { fprintf(stderr, "please execute the following\n"); fprintf(stderr, "adb -k -w /dev/ksyms /dev/mem <> 24) ) || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff)) || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff)) || (buf[14] != (hid_reported_by_gethostid &0xff))) { continue; } offset = offtab[j]; break; } if (offset == 0xffffffff) { fprintf(stderr, "perhaps you have a weird kernel -- failed\n"); exit(1); } printf("current hostid = %02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]); /* may as well print this out */ printf("enetaddr = %02x:%02x:%02x:%02x:%02x:%02x\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); if (!read_hostid) { if (lseek(fd,offset,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } buf[1] = hid >> 24; buf[12] = (hid >> 16) &0xff; buf[13] = (hid >> 8) &0xff; buf[14] = hid &0xff; for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; buf[15] = acc & 0xff; #ifndef TEST if (write(fd,buf,16) < 16) { fprintf(stderr, "write failed\n"); } fprintf(stderr,"new hostid is %08x\n", hid); fprintf(stderr,"now please execute the following or reboot:\n\n"); sprintf(obuf,"%u", hid); printf("adb -w -k /kernel/unix /dev/mem < #include #include #include #include #include #include "hid_flags.h" #define NHOSTID 10 static unsigned hostid[NHOSTID]={0}; static char xhostname[NHOSTID][MAXHOSTNAMELEN]; static int hid_flags[NHOSTID]; int sethostid(); int gethostname(); static struct sysent sethostid_sysent = { 5, sethostid } ; static struct vdlsys vd = { VDMAGIC_SYS, /* magic number */ "sethostid", /* name */ 0, /* syscall number (filled in automagically) */ &sethostid_sysent /* description of syscall */ }; Gethostid() { unsigned machineid; u_short gid; int i; gethostid(); machineid = u.u_r.r_val1; gid = u.u_gid; if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } } u.u_r.r_val1 = machineid; return; } Gethostname(uap) register struct a { char *namebuf; int namebuflen; } *uap; { char *hp; int hl,i; u_short gid; gid = u.u_gid; hp = hostname; hl = hostnamelen; if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTNAME) { hp = xhostname[gid-900]; hl = strlen(xhostname[gid-900]); } } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTNAME) { hp = xhostname[gid-900]; hl = strlen(xhostname[gid-900]); } } } hl++; if (hl > uap->namebuflen) hl = uap->namebuflen; if (copyout(hp, uap->namebuf, hl) < 0) { u.u_r.r_val1 = (-1); u.u_error = EFAULT; return; } u.u_r.r_val1 = 0; u.u_error = 0; return; } sethostid(uap) register struct a { int n; int flags; char *hostname; int hostnamelen; unsigned hostid; } *uap; { if (!suser()) { u.u_r.r_val1 = (-1); u.u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { u.u_r.r_val1 = (-1); u.u_error = EINVAL; return; } hid_flags[uap->n] = uap->flags; if (uap->flags & HID_HOSTID) { hostid[uap->n] = uap->hostid; } if (uap->flags & HID_HOSTNAME) { if (uap->hostnamelen >= MAXHOSTNAMELEN || uap->hostnamelen < 0) { u.u_r.r_val1 = (-1); u.u_error = EINVAL; return; } if ((copyin(uap->hostname,xhostname[uap->n],uap->hostnamelen) < 0)) { u.u_r.r_val1 = (-1); u.u_error = EFAULT; return; } xhostname[uap->n][uap->hostnamelen] = '\0'; /* null terminate */ } u.u_r.r_val1 = 0; u.u_error = 0; return; } sethostidinit(function_code, vdp, vdi, vds) unsigned int function_code; struct vddrv *vdp; addr_t vdi; struct vdstat *vds; { int i; switch (function_code) { case VDLOAD: vdp->vdd_vdtab = (struct vdlinkage *)&vd; sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = Gethostid; sysent[SYS_gethostname].sy_narg = 2; sysent[SYS_gethostname].sy_call = Gethostname; for (i=0; i #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s [hostname]\n", argv[0]); exit(1); } n=atoi(argv[1]); sscanf(argv[2], "%x", &hostid); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); if (argc == 4) { fprintf(stderr, "will set for hostname group %d set to %s\n", 900+n,argv[3]); if (syscall(SYS_sethostid, n, HID_HOSTID|HID_HOSTNAME, argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } else { if (syscall(SYS_sethostid, n, HID_HOSTID, NULL, 0, hostid)==-1) { perror(argv[0]); exit(1); } } } e moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s [hostname]\n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/spoof-solaris1/sethostid.execze of the sysent table. To find out what the limit is you can use adb adb -k /dev/ksyms /dev/mem sysentsize/D ^D # i.e. control-D You should be able to pick any unused syscall number between 1 and the number output by adb above minus 1. Alternatively just use an unused number which is less than the largest number which occurs in /etc/name_to_sysnum Now reboot your system. 2. Look at the makefile and check that the location of the C compiler is right for your system. You do NOT want to get /usr/ucb/cc. gcc should be OK. 3. Type make load This should load the sethostid call. 4. Type make sid This makes the program that allows you to modify the hostid for a particular group. e.g. Now you can modify the hostid and hostname for group 900 to be 23000000 and joe.test.com respectively by typing ./sid 0 23000000 joe.test.com You'll probably want to make sure that joe.test.com is in whatever name->ip address resolution scheme you use. (DNS,NIS, files) 6. If you like you can install sid and sethostid by typing make install If you do this, when you reboot, the sethostid module will be automatically loaded when sethostid is called (i.e. when you run sid). If you also need to "spoof" IP addresses, proceed as follows. Otherwise you can stop here. 7. To make the system think it has additional IP addresses (say the one corresponding to joe.test.com) you can use ifconfig /usr/sbin/ifconfig lo0:1 joe.test.com up # joe.test.com /usr/sbin/ifconfig lo0:2 192.1.1.1 up # also be 192.1.1.1 8. add a route to joe.test.com /usr/sbin/route add joe.test.com ratatosk 0 (where ratatosk is the real name of the local host) 9. compile and link run (in ../run) if you haven't already done this. 10. If you are running YP/NIS you need to do the following run 0 /usr/sbin/rpcbind run 0 /usr/lib/netsvc/yp/ypbind -broadcast there will be some console messages from rpcbind, but you will have two copies of rpcbind. You may also need to start up rpcbind as above for other applications. 11. If you want another host, say squirrel to be able to reach joe.test.com login to squirrel and execute route add joe.test.com ratatosk 1 (where ratatosk is the real name of the local host) then from squirrel when you "telnet joe.test.com" you'll get to ratatosk. You can unload the system call as follows. Type /usr/sbin/modinfo You'll get output which includes a line which looks something like 76 fc42d000 621 177 1 sethostid (kern_hostid v1.0) To remove the module type /usr/sbin/modunload -i 76 Replace 76 by the first number in the line output by modinfo. u.u_r.r_val1 = (-1); u.u_error = hid-1.4.3/spoof-solaris2/hid_flags.hto_sysnum to bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 1 Oct 1994 */ #include #include #include #include #include #include #include #include #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; int hid_flags[NHOSTID]; int sethostid(); struct sysent sethostid_sysent = {5,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "spoof v1.0", &sethostid_sysent, }; extern systeminfo(); extern uname(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as3 {struct utsname *up;}; int new_uname(struct as3 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); uname(uap,foo); ret = foo->r_val1; gid = creds->cr_gid; bsize = SYS_NMLN; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; break; } } } foo->r_val1 = ret; return 0; } struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { gid = creds->cr_gid; bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTID)) { if (serials[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTID)&&serials[gid - 900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } if (uap->command == SI_HOSTNAME) { gid = creds->cr_gid; bsize = (uap->count > SYS_NMLN) ? SYS_NMLN: uap->count; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct as {int n; int flags; char *hostname; int hostnamelen; unsigned int hostid;}; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { return EINVAL; } hid_flags[uap->n] = uap->flags; if (hid_flags[uap->n] & HID_HOSTID) numtos( (unsigned long)uap->hostid, &serials[uap->n][0]); if (hid_flags[uap->n] & HID_HOSTNAME) { if (uap->hostnamelen >= SYS_NMLN || uap->hostnamelen < 0) return EINVAL; if ((copyin(uap->hostname,xhostname[uap->n],uap->hostnamelen) < 0)) return EFAULT; xhostname[uap->n][uap->hostnamelen] = '\0'; /* null terminate */ } foo->r_val1 = 0; return 0; } _init(void) { int i,status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = new_uname; for (i=0; i < NHOSTID; i++) { serials[i][0] = 0; xhostname[i][0] = 0; } } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = uname; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } -------------------------------------------------------------- Here's a table which matches system models with the first byte of the hostid. This is from a posting to comp.sys.sun.admin by Andy.Behrens@coat.com 01 2/1x0 02 2/50 11 3/160 12 3/50 13 3/2x0 14 3/110 17 3/60 18 3/e 21 4/2x0 22 4/1x0 23 4/3x0 24 4/4x0 31 386i/150 or 386i/250 41 3/4x0 42 3/80 51 SPhid-1.4.3/spoof-solaris2/sid.cfrom one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); hostid=strtoul(argv[2], NULL, 16); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); fprintf(stderr, "will set for hostname group %d set to %s\n", 900+n,argv[3]); if (syscall(SYS_sethostid, n, HID_HOSTID|HID_HOSTNAME, argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; inthid-1.4.3/sysinfo.c1; } } default: { long (*real_sysinfo) (); if ((real_sysinfo = (long (*)()) dlsym (RTLD_NEXT, "sysinfo")) == 0) { errno = EINVAL; return -1; } return real_sysinfo (command, buf, count); } } } keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/dloverlay.cys/syscall.h> extern char *getenv(); #include gettimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int rc; if((rc = syscall(SYS_gettimeofday, tp, tzp)) == 0) { char *tmmod = getenv("TIMEOFDAY"); if(tmmod) { long delta = atol(tmmod); switch (*tmmod) { case '-': case '+': tp->tv_sec += delta; break; default: tp->tv_sec = delta; break; } } } return rc; } gethostid() { char *strhostid = getenv("HOSTID"); long hostid = strhostid ? strtol(strhostid, (char **)0, 16) : syscall(SYS_gethostid); return hostid; } gethostname(name, len) char *name; { char *hostname = getenv("HOSTNAME"); if(hostname && name) { strncpy(name, hostname, len); return 0; } return syscall(SYS_gethostname, name, len); } getdomainname(name, len) char *name; { char *domainname = getenv("DOMAINNAME"); if(domainname && name) { strncpy(name, domainname, len); return 0; } return syscall(SYS_getdomainname, name, len); } #include uname(name) struct utsname *name; { int rc; char *env; if( (rc = syscall(SYS_uname, name)) == 0) { /* you have to "know" the utsname structure sizes */ if(env=getenv("SYSNAME")) strncpy(name->sysname, env, 8); if(env=getenv("HOSTNAME")) strncpy(name->nodename, env, 64); if(env=getenv("RELEASE")) strncpy(name->release, env, 8); if(env=getenv("VERSION")) strncpy(name->version, env, 8); if(env=getenv("MACHINE")) strncpy(name->machine, env, 8); } return rc; } #include /* for stderr */ extern errno; /* WARNING1: this open does not implement the system v * style error if given a null path name, see open(2) * WARNING2: this does I/O, caveat if you overlay write(2). * NB: this should be expanded to decode the flags and errno */ open(path, flags, mode) char *path; { char *odebug = getenv("OPEN_DEBUG"); int fd; if(odebug) fprintf(stderr, "[pid=%d/uid=%d] open(\"%s\", %o, %o) = ", getpid(), getuid(), path, flags, mode); fd = syscall(SYS_open, path, flags, mode); if(odebug) fprintf(stderr, fd==(-1)?"[errno %d]\n":"%d\n", fd==(-1)?errno:fd); return fd; } ak; } } } foo->r_v/etc/name_to_sysnum to bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 14 Aug 1994 */ #include #include #include #include #include #include #include static char serial[16]; char xyzzy_rbuf[16]; int sethostid(); struct sysent sethostid_sysent = {1,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "simple sethostid v1.0", &sethostid_sysent, }; extern systeminfo(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if (serial[0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serial[i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } foo->r_val1 = ret; return 0; } struct as {int hostid; }; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if (!uap->hostid) { serial[0] = '\0'; foo->r_val1 = 0; } else { numtos( (unsigned long)uap->hostid, &serial[0]); foo->r_val1 = uap->hostid; } return 0; } _init(void) { int status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; serial[0] = 0; } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } (c < (buf + count)) *c++ = 0;\n"); printf("buf[count-1] = 0;\n"); printf("break;\n"); } printf("default: \nreturn(-1); \n}\n"); printf("return(strlen(buf) + 1);}\n"); } if (argc != 2) { fprintf(stderr, "usage: %s hostid\n", argv[0]); exit(1); } sscanf(argv[1], "%x", &hostid); printf("#hid-1.4.3/sethostid-simple-5.3/sid.c 2076 5624176046 12117ed quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; if (argc<2) { fprintf(stderr, "%s \n", argv[0]); exit(1); } hostid=strtoul(argv[1], NULL, 16); if (syscall(SYS_sethostid, hostid)==-1) { perror(argv[0]); exit(1); } } work and how the procedure works in Solaris 1.1 Mark Henderson 14 Aug 1994 */ #include #include #include #include #include #include #include static char serial[16]; char xyzzy_rbuf[16]; int sethostid(); struct sysent sethostid_sysent = {1,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys mhid-1.4.3/nvram-sol2.cThis program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. You use this program at your own risk. The author disclaims responsibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. Sorry about all the legal BS, but given that use of this program is dangerous and inexperienced people will use it, I don't have much choice from both an ethical and legal point of view. */ /* * getobphostid - gets hostid according to the openprom driver * returns 0 on failure */ unsigned int getobphostid() { struct opio { unsigned int size; unsigned char arr[OPROMMAXPARAM]; } foo; int fd,done = 0; if ((fd = open("/dev/openprom", O_RDONLY)) < 0) { return (0); } foo.size = OPROMMAXPARAM; memset(&foo.arr[0],0,OPROMMAXPARAM); if (ioctl(fd, OPROMNEXT, &foo) < 0) { return(0); } foo.size = OPROMMAXPARAM; memset(&foo.arr[0],0,OPROMMAXPARAM); for (;!done;) { foo.size = OPROMMAXPARAM; if (ioctl(fd, OPROMNXTPROP, &foo) < 0) { return(0); } if (foo.size == 0) /* not on list ! */ return 0; if (strncmp(&foo.arr[0], "idprom", 6)) continue; strcpy(&foo.arr[0],&foo.arr[0]); foo.size=OPROMMAXPARAM; if (ioctl(fd, OPROMGETPROP, &foo) < 0) { return(0); } done=1; } close(fd); return ((foo.arr[1] << 24)|(foo.arr[12] << 16)|(foo.arr[13] << 8) |(foo.arr[14])); } #define OFFSET1 017730 /* for Sun 4m */ #define OFFSET2 03730 /* for Sun 4c */ /* #define TEST /* doesn't actually do mods if TEST is defined */ unsigned char buf[17]; /* larger than it needs to be */ /* offset table -- in ascending order of magnitude */ off_t offtab[2] = { OFFSET2, OFFSET1 }; #define nofftab (sizeof(offtab) / sizeof(off_t)) off_t offset; struct nlist nl[2]; unsigned int bsd_gethostid() { unsigned char buf[1024]; buf[0] = 0; sysinfo(SI_HW_SERIAL, buf, 1024); return (strtoul(buf,NULL,10)); } void check_eeprom_driver() { int kmem; off_t where; unsigned int kbuf[12]; fprintf(stderr,"nvram-sol2 - Mark Henderson \n"); fprintf(stderr, "Placed in the public domain by the author - Jan 1995\n\n"); fprintf(stderr, "This program is distributed in the hope that it will be useful,\n"); fprintf(stderr, "but without any warranty; without even the implied warranty of\n"); fprintf(stderr, "merchantability or fitness for a particular purpose. You use\n"); fprintf(stderr, "this program at your own risk. The author disclaims responsibility for\n"); fprintf(stderr, "any damages that might result from the use of this program, even\n"); fprintf(stderr, "if they result from negligence on the part of the author.\n"); fprintf(stderr, "Malfunction or misuse of this program can damage your computer.\n\n"); if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) { fprintf(stderr, "cannot open /dev/kmem\n"); exit(1); } nl[0].n_name = "nvram"; nl[1].n_name = NULL; if (nlist("/dev/ksyms", nl) < 0) { fprintf(stderr, "cannot read namelist out of /vmunix\n"); exit(1); } if ((where = nl[0].n_value) == 0) { fprintf(stderr, "unknown kernel variable nvram\n"); fprintf(stderr, "execute the following and try again\n"); fprintf(stderr, "/usr/sbin/modload /kernel/drv/eeprom\n"); exit(1); } if (lseek(kmem, where, SEEK_SET) == (-1)) { fprintf(stderr, "lseek on /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } if (read(kmem, (char *)&kbuf[0], 48) < 48) { fprintf(stderr, "read from /dev/kmem failed\n"); fprintf(stderr, "your kernel is strange - nvram modifier won't operate\n"); exit(1); } close(kmem); if (kbuf[11] == 0x9422a028) { fprintf(stderr, "please execute the following\n"); fprintf(stderr, "adb -k -w /dev/ksyms /dev/mem <> 24) ) || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff)) || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff)) || (buf[14] != (hid_reported_by_gethostid &0xff))) { continue; } offset = offtab[j]; break; } if (offset == 0xffffffff) { fprintf(stderr, "perhaps you have a weird kernel -- failed\n"); exit(1); } printf("current hostid = %02x%02x%02x%02x\n", buf[1], buf[12], buf[13], buf[14]); /* may as well print this out */ printf("enetaddr = %02x:%02x:%02x:%02x:%02x:%02x\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); if (!read_hostid) { if (lseek(fd,offset,SEEK_SET) < 0) { fprintf(stderr, "lseek failed\n"); exit(1); } buf[1] = hid >> 24; buf[12] = (hid >> 16) &0xff; buf[13] = (hid >> 8) &0xff; buf[14] = hid &0xff; for (acc = 0 , i=0; i<15; i++) acc^=buf[i]; buf[15] = acc & 0xff; #ifndef TEST if (write(fd,buf,16) < 16) { fprintf(stderr, "write failed\n"); } fprintf(stderr,"new hostid is %08x\n", hid); fprintf(stderr,"now please execute the following or reboot:\n\n"); sprintf(obuf,"%u", hid); printf("adb -w -k /kernel/unix /dev/mem < #include #include #include #include #include #include "hid_flags.h" #define NHOSTID 10 static unsigned hostid[NHOSTID]={0}; static char xhostname[NHOSTID][MAXHOSTNAMELEN]; static int hid_flags[NHOSTID]; int sethostid(); int gethostname(); static struct sysent sethostid_sysent = { 5, sethostid } ; static struct vdlsys vd = { VDMAGIC_SYS, /* magic number */ "sethostid", /* name */ 0, /* syscall number (filled in automagically) */ &sethostid_sysent /* description of syscall */ }; Gethostid() { unsigned machineid; u_short gid; int i; gethostid(); machineid = u.u_r.r_val1; gid = u.u_gid; if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTID) { u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid; return; } } } u.u_r.r_val1 = machineid; return; } Gethostname(uap) register struct a { char *namebuf; int namebuflen; } *uap; { char *hp; int hl,i; u_short gid; gid = u.u_gid; hp = hostname; hl = hostnamelen; if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTNAME) { hp = xhostname[gid-900]; hl = strlen(xhostname[gid-900]); } } i = 0; while (gid=u.u_groups[i++]) { if (gid >= 900 && gid < 900+NHOSTID) { if (hid_flags[gid-900] & HID_HOSTNAME) { hp = xhostname[gid-900]; hl = strlen(xhostname[gid-900]); } } } hl++; if (hl > uap->namebuflen) hl = uap->namebuflen; if (copyout(hp, uap->namebuf, hl) < 0) { u.u_r.r_val1 = (-1); u.u_error = EFAULT; return; } u.u_r.r_val1 = 0; u.u_error = 0; return; } sethostid(uap) register struct a { int n; int flags; char *hostname; int hostnamelen; unsigned hostid; } *uap; { if (!suser()) { u.u_r.r_val1 = (-1); u.u_error = EACCES; return; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { u.u_r.r_val1 = (-1); u.u_error = EINVAL; return; } hid_flags[uap->n] = uap->flags; if (uap->flags & HID_HOSTID) { hostid[uap->n] = uap->hostid; } if (uap->flags & HID_HOSTNAME) { if (uap->hostnamelen >= MAXHOSTNAMELEN || uap->hostnamelen < 0) { u.u_r.r_val1 = (-1); u.u_error = EINVAL; return; } if ((copyin(uap->hostname,xhostname[uap->n],uap->hostnamelen) < 0)) { u.u_r.r_val1 = (-1); u.u_error = EFAULT; return; } xhostname[uap->n][uap->hostnamelen] = '\0'; /* null terminate */ } u.u_r.r_val1 = 0; u.u_error = 0; return; } sethostidinit(function_code, vdp, vdi, vds) unsigned int function_code; struct vddrv *vdp; addr_t vdi; struct vdstat *vds; { int i; switch (function_code) { case VDLOAD: vdp->vdd_vdtab = (struct vdlinkage *)&vd; sysent[SYS_gethostid].sy_narg = 2; sysent[SYS_gethostid].sy_call = Gethostid; sysent[SYS_gethostname].sy_narg = 2; sysent[SYS_gethostname].sy_call = Gethostname; for (i=0; i #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s [hostname]\n", argv[0]); exit(1); } n=atoi(argv[1]); sscanf(argv[2], "%x", &hostid); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); if (argc == 4) { fprintf(stderr, "will set for hostname group %d set to %s\n", 900+n,argv[3]); if (syscall(SYS_sethostid, n, HID_HOSTID|HID_HOSTNAME, argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } else { if (syscall(SYS_sethostid, n, HID_HOSTID, NULL, 0, hostid)==-1) { perror(argv[0]); exit(1); } } } e moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<3) { fprintf(stderr, "%s [hostname]\n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/spoof-solaris1/sethostid.execsent table. To find out what the limit is you can use adb adb -k /dev/ksyms /dev/mem sysentsize/D ^D # i.e. control-D You should be able to pick any unused syscall number between 1 and the number output by adb above minus 1. Alternatively just use an unused number which is less than the largest number which occurs in /etc/name_to_sysnum Now reboot your system. 2. Look at the makefile and check that the location of the C compiler is right for your system. You do NOT want to get /usr/ucb/cc. gcc should be OK. 3. Type make load This should load the sethostid call. 4. Type make sid This makes the program that allows you to modify the hostid for a particular group. e.g. Now you can modify the hostid and hostname for group 900 to be 23000000 and joe.test.com respectively by typing ./sid 0 23000000 joe.test.com You'll probably want to make sure that joe.test.com is in whatever name->ip address resolution scheme you use. (DNS,NIS, files) 6. If you like you can install sid and sethostid by typing make install If you do this, when you reboot, the sethostid module will be automatically loaded when sethostid is called (i.e. when you run sid). If you also need to "spoof" IP addresses, proceed as follows. Otherwise you can stop here. 7. To make the system think it has additional IP addresses (say the one corresponding to joe.test.com) you can use ifconfig /usr/sbin/ifconfig lo0:1 joe.test.com up # joe.test.com /usr/sbin/ifconfig lo0:2 192.1.1.1 up # also be 192.1.1.1 8. add a route to joe.test.com /usr/sbin/route add joe.test.com ratatosk 0 (where ratatosk is the real name of the local host) 9. compile and link run (in ../run) if you haven't already done this. 10. If you are running YP/NIS you need to do the following run 0 /usr/sbin/rpcbind run 0 /usr/lib/netsvc/yp/ypbind -broadcast there will be some console messages from rpcbind, but you will have two copies of rpcbind. You may also need to start up rpcbind as above for other applications. 11. If you want another host, say squirrel to be able to reach joe.test.com login to squirrel and execute route add joe.test.com ratatosk 1 (where ratatosk is the real name of the local host) then from squirrel when you "telnet joe.test.com" you'll get to ratatosk. You can unload the system call as follows. Type /usr/sbin/modinfo You'll get output which includes a line which looks something like 76 fc42d000 621 177 1 sethostid (kern_hostid v1.0) To remove the module type /usr/sbin/modunload -i 76 Replace 76 by the first number in the line output by modinfo. u.u_r.r_val1 = (-1); u.u_error = hid-1.4.3/spoof-solaris2/hid_flags.h bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 1 Oct 1994 */ #include #include #include #include #include #include #include #include #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; int hid_flags[NHOSTID]; int sethostid(); struct sysent sethostid_sysent = {5,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "spoof v1.0", &sethostid_sysent, }; extern systeminfo(); extern uname(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as3 {struct utsname *up;}; int new_uname(struct as3 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); uname(uap,foo); ret = foo->r_val1; gid = creds->cr_gid; bsize = SYS_NMLN; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; break; } } } foo->r_val1 = ret; return 0; } struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { gid = creds->cr_gid; bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTID)) { if (serials[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTID)&&serials[gid - 900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } if (uap->command == SI_HOSTNAME) { gid = creds->cr_gid; bsize = (uap->count > SYS_NMLN) ? SYS_NMLN: uap->count; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct as {int n; int flags; char *hostname; int hostnamelen; unsigned int hostid;}; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { return EINVAL; } hid_flags[uap->n] = uap->flags; if (hid_flags[uap->n] & HID_HOSTID) numtos( (unsigned long)uap->hostid, &serials[uap->n][0]); if (hid_flags[uap->n] & HID_HOSTNAME) { if (uap->hostnamelen >= SYS_NMLN || uap->hostnamelen < 0) return EINVAL; if ((copyin(uap->hostname,xhostname[uap->n],uap->hostnamelen) < 0)) return EFAULT; xhostname[uap->n][uap->hostnamelen] = '\0'; /* null terminate */ } foo->r_val1 = 0; return 0; } _init(void) { int i,status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = new_uname; for (i=0; i < NHOSTID; i++) { serials[i][0] = 0; xhostname[i][0] = 0; } } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = uname; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } -------------------------------------------------------------- Here's a table which matches system models with the first byte of the hostid. This is from a posting to comp.sys.sun.admin by Andy.Behrens@coat.com 01 2/1x0 02 2/50 11 3/160 12 3/50 13 3/2x0 14 3/110 17 3/60 18 3/e 21 4/2x0 22 4/1x0 23 4/3x0 24 4/4x0 31 386i/150 or 386i/250 41 3/4x0 42 3/80 51 SPhid-1.4.3/spoof-solaris2/sid.cmputer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); hostid=strtoul(argv[2], NULL, 16); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); fprintf(stderr, "will set for hostname group %d set to %s\n", 900+n,argv[3]); if (syscall(SYS_sethostid, n, HID_HOSTID|HID_HOSTNAME, argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; inthid-1.4.3/sysinfo.c} default: { long (*real_sysinfo) (); if ((real_sysinfo = (long (*)()) dlsym (RTLD_NEXT, "sysinfo")) == 0) { errno = EINVAL; return -1; } return real_sysinfo (command, buf, count); } } } keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/dloverlay.c> extern char *getenv(); #include gettimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int rc; if((rc = syscall(SYS_gettimeofday, tp, tzp)) == 0) { char *tmmod = getenv("TIMEOFDAY"); if(tmmod) { long delta = atol(tmmod); switch (*tmmod) { case '-': case '+': tp->tv_sec += delta; break; default: tp->tv_sec = delta; break; } } } return rc; } gethostid() { char *strhostid = getenv("HOSTID"); long hostid = strhostid ? strtol(strhostid, (char **)0, 16) : syscall(SYS_gethostid); return hostid; } gethostname(name, len) char *name; { char *hostname = getenv("HOSTNAME"); if(hostname && name) { strncpy(name, hostname, len); return 0; } return syscall(SYS_gethostname, name, len); } getdomainname(name, len) char *name; { char *domainname = getenv("DOMAINNAME"); if(domainname && name) { strncpy(name, domainname, len); return 0; } return syscall(SYS_getdomainname, name, len); } #include uname(name) struct utsname *name; { int rc; char *env; if( (rc = syscall(SYS_uname, name)) == 0) { /* you have to "know" the utsname structure sizes */ if(env=getenv("SYSNAME")) strncpy(name->sysname, env, 8); if(env=getenv("HOSTNAME")) strncpy(name->nodename, env, 64); if(env=getenv("RELEASE")) strncpy(name->release, env, 8); if(env=getenv("VERSION")) strncpy(name->version, env, 8); if(env=getenv("MACHINE")) strncpy(name->machine, env, 8); } return rc; } #include /* for stderr */ extern errno; /* WARNING1: this open does not implement the system v * style error if given a null path name, see open(2) * WARNING2: this does I/O, caveat if you overlay write(2). * NB: this should be expanded to decode the flags and errno */ open(path, flags, mode) char *path; { char *odebug = getenv("OPEN_DEBUG"); int fd; if(odebug) fprintf(stderr, "[pid=%d/uid=%d] open(\"%s\", %o, %o) = ", getpid(), getuid(), path, flags, mode); fd = syscall(SYS_open, path, flags, mode); if(odebug) fprintf(stderr, fd==(-1)?"[errno %d]\n":"%d\n", fd==(-1)?errno:fd); return fd; } ak; } } } foo->r_vlags.h-solaris2/makefile ^D hid-1.4.3/spoof-solaris2/sethostid.cpplication has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. before you install this modify /etc/name_to_sysnum to bind sethostid to an _unused_ system call number As far as I can determine the details of how to load system calls in Solaris 2.3 are undocumented. I've done this by poking around in the header files in sys and the man pages, and extrapolating from what I know about how loadable device drivers work and how the procedure works in Solaris 1.1 Mark Henderson 1 Oct 1994 */ #include #include #include #include #include #include #include #include #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; int hid_flags[NHOSTID]; int sethostid(); struct sysent sethostid_sysent = {5,0,sethostid,0}; extern struct mod_ops mod_syscallops; static struct modlsys modlsys = { &mod_syscallops, "spoof v1.0", &sethostid_sysent, }; extern systeminfo(); extern uname(); static struct modlinkage modlinkage = { MODREV_1, /* magic number */ &modlsys, 0 }; struct as3 {struct utsname *up;}; int new_uname(struct as3 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); uname(uap,foo); ret = foo->r_val1; gid = creds->cr_gid; bsize = SYS_NMLN; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->up->nodename,ret) < 0) return EFAULT; break; } } } foo->r_val1 = ret; return 0; } struct as2 {int command; char *buf; long count;}; int new_systeminfo(struct as2 *uap, rval_t *foo) { int ret,i,bsize; gid_t gid; cred_t *creds = CRED(); systeminfo(uap,foo); ret = foo->r_val1; if (uap->command == SI_HW_SERIAL) { gid = creds->cr_gid; bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/ if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTID)) { if (serials[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTID)&&serials[gid - 900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = serials[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } if (uap->command == SI_HOSTNAME) { gid = creds->cr_gid; bsize = (uap->count > SYS_NMLN) ? SYS_NMLN: uap->count; if ((gid >= 900 && gid < 900+NHOSTID) && (hid_flags[gid-900] & HID_HOSTNAME)) { if (xhostname[gid - 900][0]) { for (i=0;i < bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; } } for (gid = 900; gid < 900+NHOSTID; gid++) { if (groupmember(gid, creds)) { if ((hid_flags[gid-900]&HID_HOSTNAME)&&xhostname[gid-900][0]) { for (i=0;i< bsize - 1;i++) xyzzy_rbuf[i] = xhostname[gid-900][i]; xyzzy_rbuf[bsize - 1] = 0; ret = strlen(xyzzy_rbuf) + 1; if (copyout(xyzzy_rbuf,uap->buf,ret) < 0) return EFAULT; break; } } } } foo->r_val1 = ret; return 0; } struct as {int n; int flags; char *hostname; int hostnamelen; unsigned int hostid;}; sethostid(struct as *uap, rval_t *foo) { cred_t *creds = CRED(); if (!suser(creds)) { return EACCES; } if ((uap->n >= NHOSTID )||(uap->n < 0)) { return EINVAL; } hid_flags[uap->n] = uap->flags; if (hid_flags[uap->n] & HID_HOSTID) numtos( (unsigned long)uap->hostid, &serials[uap->n][0]); if (hid_flags[uap->n] & HID_HOSTNAME) { if (uap->hostnamelen >= SYS_NMLN || uap->hostnamelen < 0) return EINVAL; if ((copyin(uap->hostname,xhostname[uap->n],uap->hostnamelen) < 0)) return EFAULT; xhostname[uap->n][uap->hostnamelen] = '\0'; /* null terminate */ } foo->r_val1 = 0; return 0; } _init(void) { int i,status; status = mod_install(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = new_systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = new_uname; for (i=0; i < NHOSTID; i++) { serials[i][0] = 0; xhostname[i][0] = 0; } } return status; } _fini(void) { int status; status = mod_remove(&modlinkage); if (!status) { sysent[SYS_systeminfo].sy_narg = 3; sysent[SYS_systeminfo].sy_call = systeminfo; sysent[SYS_uname].sy_narg = 1; sysent[SYS_uname].sy_call = uname; } return status; } _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } -------------------------------------------------------------- Here's a table which matches system models with the first byte of the hostid. This is from a posting to comp.sys.sun.admin by Andy.Behrens@coat.com 01 2/1x0 02 2/50 11 3/160 12 3/50 13 3/2x0 14 3/110 17 3/60 18 3/e 21 4/2x0 22 4/1x0 23 4/3x0 24 4/4x0 31 386i/150 or 386i/250 41 3/4x0 42 3/80 51 SPhid-1.4.3/spoof-solaris2/sid.csibility for any damages that might result from the use of this program, even if they result from negligence on the part of the author. Also, please don't use this program to steal software. The intended use is for emergency situations where an application has to be moved from one computer to another (e.g. in the event of a hardware malfunction) and licence keys cannot be obtained quickly from the vendor. Many vendors will not supply licence keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1]); hostid=strtoul(argv[2], NULL, 16); fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid); fprintf(stderr, "will set for hostname group %d set to %s\n", 900+n,argv[3]); if (syscall(SYS_sethostid, n, HID_HOSTID|HID_HOSTNAME, argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; inthid-1.4.3/sysinfo.c sysinfo(command, buf, count) int command; char *buf; long count; { switch (command) { case SI_HW_SERIAL: { char *hid; if ((hid = getenv ("SI_HW_SERIAL")) != 0) { strncpy (buf, hid, count); buf[count - 1] = '\0'; return strlen (hid) + 1; } } default: { long (*real_sysinfo) (); if ((real_sysinfo = (long (*)()) dlsym (RTLD_NEXT, "sysinfo")) == 0) { errno = EINVAL; return -1; } return real_sysinfo (command, buf, count); } } } keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/dloverlay.c123 7542ION system os version (eg. 5) * MACHINE machine type (eg. sun4c) * OPEN_DEBUG setting it in env prints opens on stderr * * Note: the env vars must be unset and not just nulled out to get back * the real syscall operations. * */ #include #include extern char *getenv(); #include gettimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int rc; if((rc = syscall(SYS_gettimeofday, tp, tzp)) == 0) { char *tmmod = getenv("TIMEOFDAY"); if(tmmod) { long delta = atol(tmmod); switch (*tmmod) { case '-': case '+': tp->tv_sec += delta; break; default: tp->tv_sec = delta; break; } } } return rc; } gethostid() { char *strhostid = getenv("HOSTID"); long hostid = strhostid ? strtol(strhostid, (char **)0, 16) : syscall(SYS_gethostid); return hostid; } gethostname(name, len) char *name; { char *hostname = getenv("HOSTNAME"); if(hostname && name) { strncpy(name, hostname, len); return 0; } return syscall(SYS_gethostname, name, len); } getdomainname(name, len) char *name; { char *domainname = getenv("DOMAINNAME"); if(domainname && name) { strncpy(name, domainname, len); return 0; } return syscall(SYS_getdomainname, name, len); } #include uname(name) struct utsname *name; { int rc; char *env; if( (rc = syscall(SYS_uname, name)) == 0) { /* you have to "know" the utsname structure sizes */ if(env=getenv("SYSNAME")) strncpy(name->sysname, env, 8); if(env=getenv("HOSTNAME")) strncpy(name->nodename, env, 64); if(env=getenv("RELEASE")) strncpy(name->release, env, 8); if(env=getenv("VERSION")) strncpy(name->version, env, 8); if(env=getenv("MACHINE")) strncpy(name->machine, env, 8); } return rc; } #include /* for stderr */ extern errno; /* WARNING1: this open does not implement the system v * style error if given a null path name, see open(2) * WARNING2: this does I/O, caveat if you overlay write(2). * NB: this should be expanded to decode the flags and errno */ open(path, flags, mode) char *path; { char *odebug = getenv("OPEN_DEBUG"); int fd; if(odebug) fprintf(stderr, "[pid=%d/uid=%d] open(\"%s\", %o, %o) = ", getpid(), getuid(), path, flags, mode); fd = syscall(SYS_open, path, flags, mode); if(odebug) fprintf(stderr, fd==(-1)?"[errno %d]\n":"%d\n", fd==(-1)?errno:fd); return fd; } ak; } } } foo->r_v argv[3], strlen(argv[3]), hostid)==-1) { perror(argv[0]); exit(1); } } #include #include "hid_flags.h" #define NHOSTID 10 static char serials[NHOSTID][16]; char xyzzy_rbuf[SYS_NMLN]; char xhostname[NHOSTID][SYS_NMLN]; inthid-1.4.3/sysinfo.c *buf; long count; { switch (command) { case SI_HW_SERIAL: { char *hid; if ((hid = getenv ("SI_HW_SERIAL")) != 0) { strncpy (buf, hid, count); buf[count - 1] = '\0'; return strlen (hid) + 1; } } default: { long (*real_sysinfo) (); if ((real_sysinfo = (long (*)()) dlsym (RTLD_NEXT, "sysinfo")) == 0) { errno = EINVAL; return -1; } return real_sysinfo (command, buf, count); } } } keys outside of business hours. */ #include #include #include #include "sethostid.h" #include "hid_flags.h" main(argc, argv) int argc; char *argv[]; { unsigned hostid; int n; if (argc<4) { fprintf(stderr, "%s \n", argv[0]); exit(1); } n=atoi(argv[1hid-1.4.3/dloverlay.cine type (eg. sun4c) * OPEN_DEBUG setting it in env prints opens on stderr * * Note: the env vars must be unset and not just nulled out to get back * the real syscall operations. * */ #include #include extern char *getenv(); #include gettimeofday(tp, tzp) struct timeval *tp; struct timezone *tzp; { int rc; if((rc = syscall(SYS_gettimeofday, tp, tzp)) == 0) { char *tmmod = getenv("TIMEOFDAY"); if(tmmod) { long delta = atol(tmmod); switch (*tmmod) { case '-': case '+': tp->tv_sec += delta; break; default: tp->tv_sec = delta; break; } } } return rc; } gethostid() { char *strhostid = getenv("HOSTID"); long hostid = strhostid ? strtol(strhostid, (char **)0, 16) : syscall(SYS_gethostid); return hostid; } gethostname(name, len) char *name; { char *hostname = getenv("HOSTNAME"); if(hostname && name) { strncpy(name, hostname, len); return 0; } return syscall(SYS_gethostname, name, len); } getdomainname(name, len) char *name; { char *domainname = getenv("DOMAINNAME"); if(domainname && name) { strncpy(name, domainname, len); return 0; } return syscall(SYS_getdomainname, name, len); } #include uname(name) struct utsname *name; { int rc; char *env; if( (rc = syscall(SYS_uname, name)) == 0) { /* you have to "know" the utsname structure sizes */ if(env=getenv("SYSNAME")) strncpy(name->sysname, env, 8); if(env=getenv("HOSTNAME")) strncpy(name->nodename, env, 64); if(env=getenv("RELEASE")) strncpy(name->release, env, 8); if(env=getenv("VERSION")) strncpy(name->version, env, 8); if(env=getenv("MACHINE")) strncpy(name->machine, env, 8); } return rc; } #include /* for stderr */ extern errno; /* WARNING1: this open does not implement the system v * style error if given a null path name, see open(2) * WARNING2: this does I/O, caveat if you overlay write(2). * NB: this should be expanded to decode the flags and errno */ open(path, flags, mode) char *path; { char *odebug = getenv("OPEN_DEBUG"); int fd; if(odebug) fprintf(stderr, "[pid=%d/uid=%d] open(\"%s\", %o, %o) = ", getpid(), getuid(), path, flags, mode); fd = syscall(SYS_open, path, flags, mode); if(odebug) fprintf(stderr, fd==(-1)?"[errno %d]\n":"%d\n", fd==(-1)?errno:fd); return fd; } ak; } } } foo->r_v