bootparamd.c revision 21673
1/* 2 3This code is not copyright, and is placed in the public domain. Feel free to 4use and modify. Please send modifications and/or suggestions + bug fixes to 5 6 Klas Heggemann <klas@nada.kth.se> 7 8 $FreeBSD: head/usr.sbin/bootparamd/bootparamd/bootparamd.c 21673 1997-01-14 07:20:47Z jkh $ 9 10*/ 11 12 13#include <rpc/rpc.h> 14#include <rpcsvc/yp_prot.h> 15#include <rpcsvc/ypclnt.h> 16#include "bootparam_prot.h" 17#include <stdio.h> 18#include <sys/types.h> 19#include <sys/socket.h> 20#include <netdb.h> 21#include <ctype.h> 22#include <syslog.h> 23extern int debug, dolog; 24extern unsigned long route_addr; 25extern char *bootpfile; 26 27#define MAXLEN 800 28 29struct hostent *he; 30static char buffer[MAXLEN]; 31static char hostname[MAX_MACHINE_NAME]; 32static char askname[MAX_MACHINE_NAME]; 33static char path[MAX_PATH_LEN]; 34static char domain_name[MAX_MACHINE_NAME]; 35 36 37bp_whoami_res * 38bootparamproc_whoami_1(whoami) 39bp_whoami_arg *whoami; 40{ 41 long haddr; 42 static bp_whoami_res res; 43 if (debug) 44 fprintf(stderr,"whoami got question for %d.%d.%d.%d\n", 45 255 & whoami->client_address.bp_address_u.ip_addr.net, 46 255 & whoami->client_address.bp_address_u.ip_addr.host, 47 255 & whoami->client_address.bp_address_u.ip_addr.lh, 48 255 & whoami->client_address.bp_address_u.ip_addr.impno); 49 if (dolog) 50 syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n", 51 255 & whoami->client_address.bp_address_u.ip_addr.net, 52 255 & whoami->client_address.bp_address_u.ip_addr.host, 53 255 & whoami->client_address.bp_address_u.ip_addr.lh, 54 255 & whoami->client_address.bp_address_u.ip_addr.impno); 55 56 bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr, 57 sizeof(haddr)); 58 he = gethostbyaddr((char *)&haddr,sizeof(haddr),AF_INET); 59 if ( ! he ) goto failed; 60 61 if (debug) fprintf(stderr,"This is host %s\n", he->h_name); 62 if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name); 63 64 strcpy(askname, he->h_name); 65 if (checkhost(askname, hostname) ) { 66 res.client_name = hostname; 67 getdomainname(domain_name, MAX_MACHINE_NAME); 68 res.domain_name = domain_name; 69 70 if ( res.router_address.address_type != IP_ADDR_TYPE ) { 71 res.router_address.address_type = IP_ADDR_TYPE; 72 bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4); 73 } 74 if (debug) fprintf(stderr, 75 "Returning %s %s %d.%d.%d.%d\n", 76 res.client_name, 77 res.domain_name, 78 255 & res.router_address.bp_address_u.ip_addr.net, 79 255 & res.router_address.bp_address_u.ip_addr.host, 80 255 & res.router_address.bp_address_u.ip_addr.lh, 81 255 & res.router_address.bp_address_u.ip_addr.impno); 82 if (dolog) syslog(LOG_NOTICE, 83 "Returning %s %s %d.%d.%d.%d\n", 84 res.client_name, 85 res.domain_name, 86 255 & res.router_address.bp_address_u.ip_addr.net, 87 255 & res.router_address.bp_address_u.ip_addr.host, 88 255 & res.router_address.bp_address_u.ip_addr.lh, 89 255 & res.router_address.bp_address_u.ip_addr.impno); 90 91 return(&res); 92 } 93 failed: 94 if (debug) fprintf(stderr,"whoami failed\n"); 95 if (dolog) syslog(LOG_NOTICE,"whoami failed\n"); 96 return(NULL); 97} 98 99 100bp_getfile_res * 101 bootparamproc_getfile_1(getfile) 102bp_getfile_arg *getfile; 103{ 104 char *where, *index(); 105 static bp_getfile_res res; 106 107 if (debug) 108 fprintf(stderr,"getfile got question for \"%s\" and file \"%s\"\n", 109 getfile->client_name, getfile->file_id); 110 111 if (dolog) 112 syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n", 113 getfile->client_name, getfile->file_id); 114 115 he = NULL; 116 he = gethostbyname(getfile->client_name); 117 if (! he ) goto failed; 118 119 strcpy(askname,he->h_name); 120 if (getthefile(askname, getfile->file_id,buffer)) { 121 if ( where = index(buffer,':')) { 122 /* buffer is re-written to contain the name of the info of file */ 123 strncpy(hostname, buffer, where - buffer); 124 hostname[where - buffer] = '\0'; 125 where++; 126 strcpy(path, where); 127 he = gethostbyname(hostname); 128 if ( !he ) goto failed; 129 bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4); 130 res.server_name = hostname; 131 res.server_path = path; 132 res.server_address.address_type = IP_ADDR_TYPE; 133 } 134 else { /* special for dump, answer with null strings */ 135 if (!strcmp(getfile->file_id, "dump")) { 136 res.server_name = ""; 137 res.server_path = ""; 138 res.server_address.address_type = IP_ADDR_TYPE; 139 bzero(&res.server_address.bp_address_u.ip_addr,4); 140 } else goto failed; 141 } 142 if (debug) 143 fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n", 144 res.server_name, res.server_path, 145 255 & res.server_address.bp_address_u.ip_addr.net, 146 255 & res.server_address.bp_address_u.ip_addr.host, 147 255 & res.server_address.bp_address_u.ip_addr.lh, 148 255 & res.server_address.bp_address_u.ip_addr.impno); 149 if (dolog) 150 syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n", 151 res.server_name, res.server_path, 152 255 & res.server_address.bp_address_u.ip_addr.net, 153 255 & res.server_address.bp_address_u.ip_addr.host, 154 255 & res.server_address.bp_address_u.ip_addr.lh, 155 255 & res.server_address.bp_address_u.ip_addr.impno); 156 return(&res); 157 } 158 failed: 159 if (debug) fprintf(stderr, "getfile failed for %s\n", getfile->client_name); 160 if (dolog) syslog(LOG_NOTICE, 161 "getfile failed for %s\n", getfile->client_name); 162 return(NULL); 163} 164 165/* getthefile return 1 and fills the buffer with the information 166 of the file, e g "host:/export/root/client" if it can be found. 167 If the host is in the database, but the file is not, the buffer 168 will be empty. (This makes it possible to give the special 169 empty answer for the file "dump") */ 170 171getthefile(askname,fileid,buffer) 172char *askname; 173char *fileid, *buffer; 174{ 175 FILE *bpf; 176 char *where; 177 static char *result; 178 int resultlen; 179 static char *yp_domain; 180 181 int ch, pch, fid_len, res = 0; 182 int match = 0; 183 char info[MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3]; 184 185 bpf = fopen(bootpfile, "r"); 186 if ( ! bpf ) { 187 fprintf(stderr, "No %s\n", bootpfile); 188 exit(1); 189 } 190 191 while ( fscanf(bpf, "%s", hostname) > 0 && !match ) { 192 if ( *hostname != '#' ) { /* comment */ 193 if ( ! strcmp(hostname, askname) ) { 194 match = 1; 195 } else { 196 he = gethostbyname(hostname); 197 if (he && !strcmp(he->h_name, askname)) match = 1; 198 } 199 } 200 if (*hostname == '+' ) { /* NIS */ 201 if (yp_get_default_domain(&yp_domain)) { 202 if (debug) perror("NIS"); 203 return(0); 204 } 205 if (yp_match(yp_domain, "bootparams", askname, strlen(askname), 206 &result, &resultlen)) 207 return (0); 208 if (strstr(result, fileid) == NULL) { 209 buffer[0] = '\0'; 210 } else { 211 sprintf(buffer,"%s",strchr(strstr(result,fileid), '=') + 1); 212 if (strchr(buffer, ' ') != NULL) 213 *(char *)(strchr(buffer, ' ')) = '\0'; 214 } 215 if (fclose(bpf)) 216 fprintf(stderr,"Could not close %s\n", bootpfile); 217 return(1); 218 } 219 /* skip to next entry */ 220 if ( match ) break; 221 pch = ch = getc(bpf); 222 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) { 223 pch = ch; ch = getc(bpf); 224 } 225 } 226 227 /* if match is true we read the rest of the line to get the 228 info of the file */ 229 230 if (match) { 231 fid_len = strlen(fileid); 232 while ( ! res && (fscanf(bpf,"%s", info)) > 0) { /* read a string */ 233 ch = getc(bpf); /* and a character */ 234 if ( *info != '#' ) { /* Comment ? */ 235 if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') { 236 where = info + fid_len + 1; 237 if ( isprint( *where )) { 238 strcpy(buffer, where); /* found file */ 239 res = 1; break; 240 } 241 } else { 242 while (isspace(ch) && ch != '\n') ch = getc(bpf); 243 /* read to end of line */ 244 if ( ch == '\n' ) { /* didn't find it */ 245 res = -1; break; /* but host is there */ 246 } 247 if ( ch == '\\' ) { /* more info */ 248 ch = getc(bpf); /* maybe on next line */ 249 if (ch == '\n') continue; /* read it in next loop */ 250 ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */ 251 } else ungetc(ch, bpf); /* but who know what a `\` is */ 252 } /* needed for. */ 253 } else break; /* a commented rest-of-line */ 254 } 255 } 256 if (fclose(bpf)) { fprintf(stderr,"Could not close %s\n", bootpfile); } 257 if ( res == -1) buffer[0] = '\0'; /* host found, file not */ 258 return(match); 259} 260 261/* checkhost puts the hostname found in the database file in 262 the hostname-variable and returns 1, if askname is a valid 263 name for a host in the database */ 264 265checkhost(askname, hostname) 266char *askname; 267char *hostname; 268{ 269 int ch, pch; 270 FILE *bpf; 271 int res = 0; 272 static char *result; 273 int resultlen; 274 static char *yp_domain; 275 276/* struct hostent *cmp_he;*/ 277 278 bpf = fopen(bootpfile, "r"); 279 if ( ! bpf ) { 280 fprintf(stderr, "No %s\n", bootpfile); 281 exit(1); 282 } 283 284 while ( fscanf(bpf, "%s", hostname) > 0 ) { 285 if ( *hostname != '#' ) { /* comment */ 286 if ( ! strcmp(hostname, askname) ) { 287 /* return true for match of hostname */ 288 res = 1; 289 break; 290 } else { 291 /* check the alias list */ 292 he = NULL; 293 he = gethostbyname(hostname); 294 if (he && !strcmp(askname, he->h_name)) { 295 res = 1; 296 break; 297 } 298 } 299 } 300 if (*hostname == '+' ) { /* NIS */ 301 if (yp_get_default_domain(&yp_domain)) { 302 if (debug) perror("NIS"); 303 return(0); 304 } 305 if (!yp_match(yp_domain, "bootparams", askname, strlen(askname), 306 &result, &resultlen)) { 307 /* return true for match of hostname */ 308 he = NULL; 309 he = gethostbyname(askname); 310 if (he && !strcmp(askname, he->h_name)) { 311 res = 1; 312 sprintf(hostname,"%s", he->h_name); 313 } 314 } 315 if (fclose(bpf)) 316 fprintf(stderr,"Could not close %s\n", bootpfile); 317 return(res); 318 } 319 /* skip to next entry */ 320 pch = ch = getc(bpf); 321 while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) { 322 pch = ch; ch = getc(bpf); 323 } 324 } 325 if (fclose(bpf)) { fprintf(stderr,"Could not close %s\n", bootpfile); } 326 return(res); 327} 328