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