1ae115bc7Smrj /* 2ae115bc7Smrj * Open Boot Prom eeprom utility 3*23a1cceaSRoger A. Faulkner */ 4*23a1cceaSRoger A. Faulkner 5*23a1cceaSRoger A. Faulkner /* 6*23a1cceaSRoger A. Faulkner * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 7ae115bc7Smrj */ 8ae115bc7Smrj 9ae115bc7Smrj /* 10ae115bc7Smrj * Copyright (c) 1983 Regents of the University of California. 11ae115bc7Smrj * All rights reserved. The Berkeley software License Agreement 12ae115bc7Smrj * specifies the terms and conditions for redistribution. 13ae115bc7Smrj */ 14ae115bc7Smrj 15ae115bc7Smrj #include <sys/types.h> 16ae115bc7Smrj #include <sys/param.h> 17ae115bc7Smrj #include <sys/openpromio.h> 18ae115bc7Smrj #include <stdio.h> 19ae115bc7Smrj #include <fcntl.h> 20ae115bc7Smrj #include <string.h> 21ae115bc7Smrj #include <errno.h> 22ae115bc7Smrj #include <stdlib.h> 23ae115bc7Smrj #include <unistd.h> 24ae115bc7Smrj 25ae115bc7Smrj /* 26ae115bc7Smrj * Usage: % eeprom [-v] [-f promdev] [-] 27ae115bc7Smrj * % eeprom [-v] [-f promdev] field[=value] ... 28ae115bc7Smrj */ 29ae115bc7Smrj 30ae115bc7Smrj /* 31ae115bc7Smrj * 128 is the size of the largest (currently) property name buffer 32ae115bc7Smrj * 8192 - MAXPROPSIZE - sizeof (int) is the size of the largest 33ae115bc7Smrj * (currently) property value, viz. nvramrc. 34ae115bc7Smrj * the sizeof(u_int) is from struct openpromio 35ae115bc7Smrj */ 36ae115bc7Smrj 37ae115bc7Smrj #define MAXPROPSIZE 128 38ae115bc7Smrj #define MAXNAMESIZE MAXPROPSIZE 39ae115bc7Smrj #define MAXVALSIZE (8192 - MAXPROPSIZE - sizeof (uint_t)) 40ae115bc7Smrj #define BUFSIZE (MAXPROPSIZE + MAXVALSIZE + sizeof (uint_t)) 41ae115bc7Smrj typedef union { 42ae115bc7Smrj char buf[BUFSIZE]; 43ae115bc7Smrj struct openpromio opp; 44ae115bc7Smrj } Oppbuf; 45ae115bc7Smrj 46ae115bc7Smrj extern int _error(int do_perror, char *fmt, ...); 47*23a1cceaSRoger A. Faulkner extern void setpname(char *); 48ae115bc7Smrj static int get_password(char *, int); 49ae115bc7Smrj extern int loadlogo(char *, int, int, char *); 50ae115bc7Smrj 51ae115bc7Smrj #define NO_PERROR 0 52ae115bc7Smrj #define PERROR 1 53ae115bc7Smrj 54ae115bc7Smrj static int prom_fd; 55ae115bc7Smrj static char *promdev; 56ae115bc7Smrj static int verbose; 57ae115bc7Smrj 58ae115bc7Smrj static void do_var(char *); 59ae115bc7Smrj static void dump_all(); 60ae115bc7Smrj static void print_one(char *); 61ae115bc7Smrj static void set_one(char *, char *); 62ae115bc7Smrj static void promclose(); 63ae115bc7Smrj static int promopen(int); 64ae115bc7Smrj 65ae115bc7Smrj static int getpropval(struct openpromio *); 66ae115bc7Smrj static int setpropval(struct openpromio *); 67ae115bc7Smrj 68ae115bc7Smrj static char *badarchmsg = "Architecture does not support this command.\n"; 69ae115bc7Smrj 70ae115bc7Smrj typedef void (*func)(); 71ae115bc7Smrj 72ae115bc7Smrj 73ae115bc7Smrj /* We have to special-case two properties related to security */ 74ae115bc7Smrj static void i_secure(); 75ae115bc7Smrj static void i_passwd(), o_passwd(); 76ae115bc7Smrj static void i_oemlogo(); 77ae115bc7Smrj 78ae115bc7Smrj /* 79ae115bc7Smrj * It's unfortunate that we have to know the names of certain properties 80ae115bc7Smrj * in this program (the whole idea of openprom was to avoid it), but at 81ae115bc7Smrj * least we can isolate them to these defines here. 82ae115bc7Smrj */ 83ae115bc7Smrj #define PASSWORD_PROPERTY "security-password" 84ae115bc7Smrj #define MODE_PROPERTY "security-mode" 85ae115bc7Smrj #define LOGO_PROPERTY "oem-logo" 86ae115bc7Smrj #define PW_SIZE 8 87ae115bc7Smrj 88ae115bc7Smrj /* 89ae115bc7Smrj * Unlike the old-style eeprom command, where every property needed an 90ae115bc7Smrj * i_foo and an o_foo function, we only need them when the default case 91ae115bc7Smrj * isn't sufficient. 92ae115bc7Smrj */ 93ae115bc7Smrj static struct opvar { 94ae115bc7Smrj char *name; 95ae115bc7Smrj func in; 96ae115bc7Smrj func out; 97ae115bc7Smrj } opvar[] = { 98ae115bc7Smrj #define e(n, i, o) {n, i, o} 99ae115bc7Smrj e(MODE_PROPERTY, i_secure, (func)NULL), 100ae115bc7Smrj e(PASSWORD_PROPERTY, i_passwd, o_passwd), 101ae115bc7Smrj e(LOGO_PROPERTY, i_oemlogo, (func)NULL), 102ae115bc7Smrj { (char *)NULL, (func)NULL, (func)NULL} 103ae115bc7Smrj #undef e 104ae115bc7Smrj }; 105ae115bc7Smrj 106ae115bc7Smrj 107ae115bc7Smrj /* 108ae115bc7Smrj * sun4c openprom 109ae115bc7Smrj */ 110ae115bc7Smrj 111ae115bc7Smrj int 112ae115bc7Smrj main(int argc, char **argv) 113ae115bc7Smrj { 114ae115bc7Smrj int c; 115ae115bc7Smrj extern char *optarg; 116ae115bc7Smrj extern int optind; 117ae115bc7Smrj 118ae115bc7Smrj promdev = "/dev/openprom"; 119ae115bc7Smrj 120ae115bc7Smrj while ((c = getopt(argc, argv, "cif:v")) != -1) 121ae115bc7Smrj switch (c) { 122ae115bc7Smrj case 'c': 123ae115bc7Smrj case 'i': 124ae115bc7Smrj /* ignore for openprom */ 125ae115bc7Smrj break; 126ae115bc7Smrj case 'v': 127ae115bc7Smrj verbose++; 128ae115bc7Smrj break; 129ae115bc7Smrj case 'f': 130ae115bc7Smrj promdev = optarg; 131ae115bc7Smrj break; 132ae115bc7Smrj default: 133ae115bc7Smrj exit(_error(NO_PERROR, 134ae115bc7Smrj "Usage: %s [-v] [-f prom-device] " 135ae115bc7Smrj "[variable[=value] ...]", argv[0])); 136ae115bc7Smrj } 137ae115bc7Smrj 138*23a1cceaSRoger A. Faulkner setpname(argv[0]); 139ae115bc7Smrj 140ae115bc7Smrj /* 141ae115bc7Smrj * If no arguments, dump all fields. 142ae115bc7Smrj */ 143ae115bc7Smrj if (optind >= argc) { 144ae115bc7Smrj dump_all(); 145ae115bc7Smrj exit(0); 146ae115bc7Smrj } 147ae115bc7Smrj 148ae115bc7Smrj while (optind < argc) { 149ae115bc7Smrj /* 150ae115bc7Smrj * If "-" specified, read variables from stdin. 151ae115bc7Smrj */ 152ae115bc7Smrj if (strcmp(argv[optind], "-") == 0) { 153ae115bc7Smrj int c; 154ae115bc7Smrj char *nl, line[BUFSIZE]; 155ae115bc7Smrj 156ae115bc7Smrj while (fgets(line, sizeof (line), stdin) != NULL) { 157ae115bc7Smrj /* zap newline if present */ 158ae115bc7Smrj if (nl = strchr(line, '\n')) 159ae115bc7Smrj *nl = 0; 160ae115bc7Smrj /* otherwise discard rest of line */ 161ae115bc7Smrj else 162ae115bc7Smrj while ((c = getchar()) != '\n' && 163ae115bc7Smrj c != EOF) 164ae115bc7Smrj /* nothing */; 165ae115bc7Smrj 166ae115bc7Smrj do_var(line); 167ae115bc7Smrj } 168ae115bc7Smrj clearerr(stdin); 169ae115bc7Smrj } 170ae115bc7Smrj /* 171ae115bc7Smrj * Process each argument as a variable print or set request. 172ae115bc7Smrj */ 173ae115bc7Smrj else 174ae115bc7Smrj do_var(argv[optind]); 175ae115bc7Smrj 176ae115bc7Smrj optind++; 177ae115bc7Smrj } 178ae115bc7Smrj return (0); 179ae115bc7Smrj } 180ae115bc7Smrj 181ae115bc7Smrj /* 182ae115bc7Smrj * Print or set an EEPROM field. 183ae115bc7Smrj */ 184ae115bc7Smrj static void 185ae115bc7Smrj do_var(char *var) 186ae115bc7Smrj { 187ae115bc7Smrj char *val; 188ae115bc7Smrj 189ae115bc7Smrj val = strchr(var, '='); 190ae115bc7Smrj 191ae115bc7Smrj if (val == NULL) { 192ae115bc7Smrj /* 193ae115bc7Smrj * print specific property 194ae115bc7Smrj */ 195ae115bc7Smrj if (promopen(O_RDONLY)) { 196ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 197ae115bc7Smrj exit(1); 198ae115bc7Smrj } 199ae115bc7Smrj print_one(var); 200ae115bc7Smrj } else { 201ae115bc7Smrj /* 202ae115bc7Smrj * set specific property to value 203ae115bc7Smrj */ 204ae115bc7Smrj *val++ = '\0'; 205ae115bc7Smrj 206ae115bc7Smrj if (promopen(O_RDWR)) { 207ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 208ae115bc7Smrj exit(1); 209ae115bc7Smrj } 210ae115bc7Smrj set_one(var, val); 211ae115bc7Smrj } 212ae115bc7Smrj promclose(); 213ae115bc7Smrj } 214ae115bc7Smrj 215ae115bc7Smrj /* 216ae115bc7Smrj * Print all properties and values 217ae115bc7Smrj */ 218ae115bc7Smrj static void 219ae115bc7Smrj dump_all() 220ae115bc7Smrj { 221ae115bc7Smrj Oppbuf oppbuf; 222ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 223ae115bc7Smrj 224ae115bc7Smrj if (promopen(O_RDONLY)) { 225ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 226ae115bc7Smrj exit(1); 227ae115bc7Smrj } 228ae115bc7Smrj /* get first prop by asking for null string */ 229ae115bc7Smrj (void) memset(oppbuf.buf, '\0', BUFSIZE); 230ae115bc7Smrj /* CONSTCOND */ 231ae115bc7Smrj while (1) { 232ae115bc7Smrj /* 233ae115bc7Smrj * get property 234ae115bc7Smrj */ 235ae115bc7Smrj opp->oprom_size = MAXPROPSIZE; 236ae115bc7Smrj 237ae115bc7Smrj if (ioctl(prom_fd, OPROMNXTOPT, opp) < 0) 238ae115bc7Smrj exit(_error(PERROR, "OPROMNXTOPT")); 239ae115bc7Smrj 240ae115bc7Smrj if (opp->oprom_size == 0) { 241ae115bc7Smrj promclose(); 242ae115bc7Smrj return; 243ae115bc7Smrj } 244ae115bc7Smrj print_one(opp->oprom_array); 245ae115bc7Smrj } 246ae115bc7Smrj } 247ae115bc7Smrj 248ae115bc7Smrj /* 249ae115bc7Smrj * Print one property and its value. 250ae115bc7Smrj */ 251ae115bc7Smrj static void 252ae115bc7Smrj print_one(char *var) 253ae115bc7Smrj { 254ae115bc7Smrj Oppbuf oppbuf; 255ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 2563b133becSGangadhar Mylapuram char bootargs[MAXVALSIZE]; 2573b133becSGangadhar Mylapuram 2583b133becSGangadhar Mylapuram if (strcmp(var, "bootcmd") == 0) { 2593b133becSGangadhar Mylapuram opp->oprom_size = MAXVALSIZE; 2603b133becSGangadhar Mylapuram if (ioctl(prom_fd, OPROMGETBOOTARGS, opp) < 0) { 2613b133becSGangadhar Mylapuram (void) _error(PERROR, "OPROMGETBOOTARGS"); 2623b133becSGangadhar Mylapuram return; 2633b133becSGangadhar Mylapuram } 2643b133becSGangadhar Mylapuram (void) strlcpy(bootargs, opp->oprom_array, MAXVALSIZE); 2653b133becSGangadhar Mylapuram 2663b133becSGangadhar Mylapuram opp->oprom_size = MAXVALSIZE; 2673b133becSGangadhar Mylapuram if (ioctl(prom_fd, OPROMGETBOOTPATH, opp) < 0) { 2683b133becSGangadhar Mylapuram (void) _error(PERROR, "OPROMGETBOOTPATH"); 2693b133becSGangadhar Mylapuram return; 2703b133becSGangadhar Mylapuram } 2713b133becSGangadhar Mylapuram (void) printf("%s=%s %s\n", var, opp->oprom_array, bootargs); 2723b133becSGangadhar Mylapuram return; 2733b133becSGangadhar Mylapuram } 274ae115bc7Smrj 275ae115bc7Smrj (void) strlcpy(opp->oprom_array, var, MAXNAMESIZE); 276ae115bc7Smrj if (getpropval(opp) || opp->oprom_size <= 0) 277ae115bc7Smrj (void) printf("%s: data not available.\n", var); 278ae115bc7Smrj else { 279ae115bc7Smrj /* If necessary, massage the output */ 280ae115bc7Smrj struct opvar *v; 281ae115bc7Smrj 282ae115bc7Smrj for (v = opvar; v->name; v++) 283ae115bc7Smrj if (strcmp(var, v->name) == 0) 284ae115bc7Smrj break; 285ae115bc7Smrj 286ae115bc7Smrj if (v->name && v->out) 287ae115bc7Smrj (*v->out)(v->name, opp->oprom_array); 288ae115bc7Smrj else 289ae115bc7Smrj (void) printf("%s=%s\n", var, opp->oprom_array); 290ae115bc7Smrj } 291ae115bc7Smrj } 292ae115bc7Smrj 293ae115bc7Smrj /* 294ae115bc7Smrj * Set one property to the given value. 295ae115bc7Smrj */ 296ae115bc7Smrj static void 297ae115bc7Smrj set_one(char *var, char *val) 298ae115bc7Smrj { 299ae115bc7Smrj Oppbuf oppbuf; 300ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 301ae115bc7Smrj struct opvar *v; 302ae115bc7Smrj 303ae115bc7Smrj if (verbose) { 304ae115bc7Smrj (void) printf("old:"); 305ae115bc7Smrj print_one(var); 306ae115bc7Smrj } 307ae115bc7Smrj 308ae115bc7Smrj /* If necessary, massage the input */ 309ae115bc7Smrj 310ae115bc7Smrj for (v = opvar; v->name; v++) 311ae115bc7Smrj if (strcmp(var, v->name) == 0) 312ae115bc7Smrj break; 313ae115bc7Smrj 314ae115bc7Smrj if (v->name && v->in) 315ae115bc7Smrj (*v->in)(v->name, val, opp); 316ae115bc7Smrj else { 317ae115bc7Smrj int varlen = strlen(var) + 1; 318ae115bc7Smrj int vallen = strlen(val); 319ae115bc7Smrj 320ae115bc7Smrj if (varlen > MAXNAMESIZE) { 321ae115bc7Smrj (void) printf("%s: invalid property.\n", var); 322ae115bc7Smrj return; 323ae115bc7Smrj } 324ae115bc7Smrj if (vallen >= MAXVALSIZE) { 325ae115bc7Smrj (void) printf("%s: invalid property value.\n", var); 326ae115bc7Smrj return; 327ae115bc7Smrj } 328ae115bc7Smrj (void) strcpy(opp->oprom_array, var); 329ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen, val); 330ae115bc7Smrj opp->oprom_size = varlen + vallen; 331ae115bc7Smrj if (setpropval(opp)) 332ae115bc7Smrj (void) printf("%s: invalid property.\n", var); 333ae115bc7Smrj } 334ae115bc7Smrj 335ae115bc7Smrj if (verbose) { 336ae115bc7Smrj (void) printf("new:"); 337ae115bc7Smrj print_one(var); 338ae115bc7Smrj } 339ae115bc7Smrj } 340ae115bc7Smrj 341ae115bc7Smrj static int 342ae115bc7Smrj promopen(int oflag) 343ae115bc7Smrj { 344ae115bc7Smrj /* CONSTCOND */ 345ae115bc7Smrj while (1) { 346ae115bc7Smrj if ((prom_fd = open(promdev, oflag)) < 0) { 347ae115bc7Smrj if (errno == EAGAIN) 348ae115bc7Smrj continue; 349ae115bc7Smrj else if (errno == ENXIO) 350ae115bc7Smrj return (-1); 351ae115bc7Smrj else 352ae115bc7Smrj exit(_error(PERROR, "cannot open %s", promdev)); 353ae115bc7Smrj } else 354ae115bc7Smrj break; 355ae115bc7Smrj } 356ae115bc7Smrj return (0); 357ae115bc7Smrj } 358ae115bc7Smrj 359ae115bc7Smrj static void 360ae115bc7Smrj promclose() 361ae115bc7Smrj { 362ae115bc7Smrj if (close(prom_fd) < 0) 363ae115bc7Smrj exit(_error(PERROR, "close error on %s", promdev)); 364ae115bc7Smrj } 365ae115bc7Smrj 366ae115bc7Smrj static int 367ae115bc7Smrj getpropval(struct openpromio *opp) 368ae115bc7Smrj { 369ae115bc7Smrj opp->oprom_size = MAXVALSIZE; 370ae115bc7Smrj 371ae115bc7Smrj if (ioctl(prom_fd, OPROMGETOPT, opp) < 0) 372ae115bc7Smrj return (_error(PERROR, "OPROMGETOPT")); 373ae115bc7Smrj 374ae115bc7Smrj return (0); 375ae115bc7Smrj } 376ae115bc7Smrj 377ae115bc7Smrj static int 378ae115bc7Smrj setpropval(struct openpromio *opp) 379ae115bc7Smrj { 380ae115bc7Smrj /* Caller must set opp->oprom_size */ 381ae115bc7Smrj 382ae115bc7Smrj if (ioctl(prom_fd, OPROMSETOPT, opp) < 0) 383ae115bc7Smrj return (_error(PERROR, "OPROMSETOPT")); 384ae115bc7Smrj return (0); 385ae115bc7Smrj } 386ae115bc7Smrj 387ae115bc7Smrj 388ae115bc7Smrj /* 389ae115bc7Smrj * The next set of functions handle the special cases. 390ae115bc7Smrj */ 391ae115bc7Smrj 392ae115bc7Smrj static void 393ae115bc7Smrj i_oemlogo(char *var, char *val, struct openpromio *opp) 394ae115bc7Smrj { 395ae115bc7Smrj int varlen = strlen(var) + 1; 396ae115bc7Smrj 397ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* safe - we know the name */ 398ae115bc7Smrj 399ae115bc7Smrj if (loadlogo(val, 64, 64, opp->oprom_array + varlen)) 400ae115bc7Smrj exit(1); 401ae115bc7Smrj opp->oprom_size = varlen + 512; 402ae115bc7Smrj if (ioctl(prom_fd, OPROMSETOPT2, opp) < 0) 403ae115bc7Smrj exit(_error(PERROR, "OPROMSETOPT2")); 404ae115bc7Smrj } 405ae115bc7Smrj 406ae115bc7Smrj /* 407ae115bc7Smrj * Set security mode. 408ae115bc7Smrj * If oldmode was none, and new mode is not none, get and set password, 409ae115bc7Smrj * too. 410ae115bc7Smrj * If old mode was not none, and new mode is none, wipe out old 411ae115bc7Smrj * password. 412ae115bc7Smrj */ 413ae115bc7Smrj static void 414ae115bc7Smrj i_secure(char *var, char *val, struct openpromio *opp) 415ae115bc7Smrj { 416ae115bc7Smrj int secure; 417ae115bc7Smrj Oppbuf oppbuf; 418ae115bc7Smrj struct openpromio *opp2 = &(oppbuf.opp); 419ae115bc7Smrj char pwbuf[PW_SIZE + 2]; 420ae115bc7Smrj int varlen1, varlen2; 421ae115bc7Smrj 422ae115bc7Smrj (void) strcpy(opp2->oprom_array, var); /* safe; we know the name */ 423ae115bc7Smrj if (getpropval(opp2) || opp2->oprom_size <= 0) { 424ae115bc7Smrj (void) printf("%s: data not available.\n", var); 425ae115bc7Smrj exit(1); 426ae115bc7Smrj } 427ae115bc7Smrj secure = strcmp(opp2->oprom_array, "none"); 428ae115bc7Smrj 429ae115bc7Smrj /* Set up opp for mode */ 430ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* safe; we know the name */ 431ae115bc7Smrj varlen1 = strlen(opp->oprom_array) + 1; 432ae115bc7Smrj if (strlen(val) > 32) { /* 32 > [ "full", "command", "none" ] */ 433ae115bc7Smrj (void) printf("Invalid security mode, mode unchanged.\n"); 434ae115bc7Smrj exit(1); 435ae115bc7Smrj } 436ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen1, val); 437ae115bc7Smrj opp->oprom_size = varlen1 + strlen(val); 438ae115bc7Smrj 439ae115bc7Smrj /* Set up opp2 for password */ 440ae115bc7Smrj (void) strcpy(opp2->oprom_array, PASSWORD_PROPERTY); 441ae115bc7Smrj varlen2 = strlen(opp2->oprom_array) + 1; 442ae115bc7Smrj 443ae115bc7Smrj if ((strcmp(val, "full") == 0) || (strcmp(val, "command") == 0)) { 444ae115bc7Smrj if (! secure) { 445ae115bc7Smrj /* no password yet, get one */ 446ae115bc7Smrj if (get_password(pwbuf, PW_SIZE)) { 447ae115bc7Smrj (void) strcpy(opp2->oprom_array + varlen2, 448ae115bc7Smrj pwbuf); 449ae115bc7Smrj opp2->oprom_size = varlen2 + strlen(pwbuf); 450ae115bc7Smrj /* set password first */ 451ae115bc7Smrj if (setpropval(opp2) || setpropval(opp)) 452ae115bc7Smrj exit(1); 453ae115bc7Smrj } else 454ae115bc7Smrj exit(1); 455ae115bc7Smrj } else { 456ae115bc7Smrj if (setpropval(opp)) 457ae115bc7Smrj exit(1); 458ae115bc7Smrj } 459ae115bc7Smrj } else if (strcmp(val, "none") == 0) { 460ae115bc7Smrj if (secure) { 461ae115bc7Smrj (void) memset(opp2->oprom_array + varlen2, '\0', 462ae115bc7Smrj PW_SIZE); 463ae115bc7Smrj opp2->oprom_size = varlen2 + PW_SIZE; 464ae115bc7Smrj /* set mode first */ 465ae115bc7Smrj if (setpropval(opp) || setpropval(opp2)) 466ae115bc7Smrj exit(1); 467ae115bc7Smrj } else { 468ae115bc7Smrj if (setpropval(opp)) 469ae115bc7Smrj exit(1); 470ae115bc7Smrj } 471ae115bc7Smrj } else { 472ae115bc7Smrj (void) printf("Invalid security mode, mode unchanged.\n"); 473ae115bc7Smrj exit(1); 474ae115bc7Smrj } 475ae115bc7Smrj } 476ae115bc7Smrj 477ae115bc7Smrj /* 478ae115bc7Smrj * Set password. 479ae115bc7Smrj * We must be in a secure mode in order to do this. 480ae115bc7Smrj */ 481ae115bc7Smrj /* ARGSUSED */ 482ae115bc7Smrj static void 483ae115bc7Smrj i_passwd(char *var, char *val, struct openpromio *opp) 484ae115bc7Smrj { 485ae115bc7Smrj int secure; 486ae115bc7Smrj Oppbuf oppbuf; 487ae115bc7Smrj struct openpromio *opp2 = &(oppbuf.opp); 488ae115bc7Smrj char pwbuf[PW_SIZE + 2]; 489ae115bc7Smrj int varlen; 490ae115bc7Smrj 491ae115bc7Smrj (void) strcpy(opp2->oprom_array, MODE_PROPERTY); 492ae115bc7Smrj if (getpropval(opp2) || opp2->oprom_size <= 0) { 493ae115bc7Smrj (void) printf("%s: data not available.\n", opp2->oprom_array); 494ae115bc7Smrj exit(1); 495ae115bc7Smrj } 496ae115bc7Smrj secure = strcmp(opp2->oprom_array, "none"); 497ae115bc7Smrj 498ae115bc7Smrj if (!secure) { 499ae115bc7Smrj (void) printf("Not in secure mode\n"); 500ae115bc7Smrj exit(1); 501ae115bc7Smrj } 502ae115bc7Smrj 503ae115bc7Smrj /* Set up opp for password */ 504ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* Safe; We know the name */ 505ae115bc7Smrj varlen = strlen(opp->oprom_array) + 1; 506ae115bc7Smrj 507ae115bc7Smrj if (get_password(pwbuf, PW_SIZE)) { 508ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen, pwbuf); /* Bounded */ 509ae115bc7Smrj opp->oprom_size = varlen + strlen(pwbuf); 510ae115bc7Smrj if (setpropval(opp)) 511ae115bc7Smrj exit(1); 512ae115bc7Smrj } else 513ae115bc7Smrj exit(1); 514ae115bc7Smrj } 515ae115bc7Smrj 516ae115bc7Smrj /* ARGSUSED */ 517ae115bc7Smrj static void 518ae115bc7Smrj o_passwd(char *var, char *val) 519ae115bc7Smrj { 520ae115bc7Smrj /* Don't print the password */ 521ae115bc7Smrj } 522ae115bc7Smrj 523ae115bc7Smrj static int 524ae115bc7Smrj get_password(char *pw_dest, int pwsize) 525ae115bc7Smrj { 526ae115bc7Smrj int insist = 0, ok, flags; 527ae115bc7Smrj int c, pwlen; 528ae115bc7Smrj char *p; 529ae115bc7Smrj static char pwbuf[256]; 530ae115bc7Smrj char *pasword = NULL; 531ae115bc7Smrj 532ae115bc7Smrj tryagain: 533ae115bc7Smrj (void) printf("Changing PROM password:\n"); 534ae115bc7Smrj if ((pasword = getpass("New password:")) == NULL) { 535ae115bc7Smrj exit(_error(NO_PERROR, "failed to get password")); 536ae115bc7Smrj } 537ae115bc7Smrj (void) strcpy(pwbuf, pasword); 538ae115bc7Smrj pwlen = strlen(pwbuf); 539ae115bc7Smrj if (pwlen == 0) { 540ae115bc7Smrj (void) printf("Password unchanged.\n"); 541ae115bc7Smrj return (0); 542ae115bc7Smrj } 543ae115bc7Smrj /* 544ae115bc7Smrj * Insure password is of reasonable length and 545ae115bc7Smrj * composition. If we really wanted to make things 546ae115bc7Smrj * sticky, we could check the dictionary for common 547ae115bc7Smrj * words, but then things would really be slow. 548ae115bc7Smrj */ 549ae115bc7Smrj ok = 0; 550ae115bc7Smrj flags = 0; 551ae115bc7Smrj p = pwbuf; 552ae115bc7Smrj while ((c = *p++) != 0) { 553ae115bc7Smrj if (c >= 'a' && c <= 'z') 554ae115bc7Smrj flags |= 2; 555ae115bc7Smrj else if (c >= 'A' && c <= 'Z') 556ae115bc7Smrj flags |= 4; 557ae115bc7Smrj else if (c >= '0' && c <= '9') 558ae115bc7Smrj flags |= 1; 559ae115bc7Smrj else 560ae115bc7Smrj flags |= 8; 561ae115bc7Smrj } 562ae115bc7Smrj if (flags >= 7 && pwlen >= 4) 563ae115bc7Smrj ok = 1; 564ae115bc7Smrj if ((flags == 2 || flags == 4) && pwlen >= 6) 565ae115bc7Smrj ok = 1; 566ae115bc7Smrj if ((flags == 3 || flags == 5 || flags == 6) && pwlen >= 5) 567ae115bc7Smrj ok = 1; 568ae115bc7Smrj if (!ok && insist < 2) { 569ae115bc7Smrj (void) printf("Please use %s.\n", flags == 1 ? 570ae115bc7Smrj "at least one non-numeric character" : "a longer password"); 571ae115bc7Smrj insist++; 572ae115bc7Smrj goto tryagain; 573ae115bc7Smrj } 574ae115bc7Smrj if (strcmp(pwbuf, getpass("Retype new password:")) != 0) { 575ae115bc7Smrj (void) printf("Mismatch - password unchanged.\n"); 576ae115bc7Smrj return (0); 577ae115bc7Smrj } 578ae115bc7Smrj (void) strncpy(pw_dest, pwbuf, pwsize); 579ae115bc7Smrj return (1); 580ae115bc7Smrj } 581