1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <locale.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <unistd.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 34*7c478bd9Sstevel@tonic-gate #include <string.h> 35*7c478bd9Sstevel@tonic-gate #include "addrem.h" 36*7c478bd9Sstevel@tonic-gate #include "errmsg.h" 37*7c478bd9Sstevel@tonic-gate #include "plcysubr.h" 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* function prototypes */ 40*7c478bd9Sstevel@tonic-gate static void usage(); 41*7c478bd9Sstevel@tonic-gate static int unload_drv(char *, int, int); 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * try to modunload driver. 46*7c478bd9Sstevel@tonic-gate * return -1 on failure and 0 on success 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate static int 49*7c478bd9Sstevel@tonic-gate unload_drv(char *driver_name, int force_flag, int verbose_flag) 50*7c478bd9Sstevel@tonic-gate { 51*7c478bd9Sstevel@tonic-gate int modid; 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate get_modid(driver_name, &modid); 54*7c478bd9Sstevel@tonic-gate if (modid != -1) { 55*7c478bd9Sstevel@tonic-gate if (modctl(MODUNLOAD, modid) < 0) { 56*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_MODUN), driver_name); 57*7c478bd9Sstevel@tonic-gate if (force_flag == 0) { /* no force flag */ 58*7c478bd9Sstevel@tonic-gate if (verbose_flag) { 59*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 60*7c478bd9Sstevel@tonic-gate gettext(NOUPDATE), driver_name); 61*7c478bd9Sstevel@tonic-gate } 62*7c478bd9Sstevel@tonic-gate /* clean up and exit. remove lock file */ 63*7c478bd9Sstevel@tonic-gate err_exit(); 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(FORCE_UPDATE), 66*7c478bd9Sstevel@tonic-gate driver_name); 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate return (-1); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate return (0); 73*7c478bd9Sstevel@tonic-gate } 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate static void 77*7c478bd9Sstevel@tonic-gate usage() 78*7c478bd9Sstevel@tonic-gate { 79*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(UPD_DRV_USAGE)); 80*7c478bd9Sstevel@tonic-gate exit(1); 81*7c478bd9Sstevel@tonic-gate } 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate int 85*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 86*7c478bd9Sstevel@tonic-gate { 87*7c478bd9Sstevel@tonic-gate int error, opt, major; 88*7c478bd9Sstevel@tonic-gate int cleanup_flag = 0; 89*7c478bd9Sstevel@tonic-gate int update_conf = 1; /* reload driver.conf by default */ 90*7c478bd9Sstevel@tonic-gate int verbose_flag = 0; /* -v option */ 91*7c478bd9Sstevel@tonic-gate int force_flag = 0; /* -f option */ 92*7c478bd9Sstevel@tonic-gate int a_flag = 0; /* -a option */ 93*7c478bd9Sstevel@tonic-gate int d_flag = 0; /* -d option */ 94*7c478bd9Sstevel@tonic-gate int i_flag = 0; /* -i option */ 95*7c478bd9Sstevel@tonic-gate int l_flag = 0; /* -l option */ 96*7c478bd9Sstevel@tonic-gate int m_flag = 0; /* -m option */ 97*7c478bd9Sstevel@tonic-gate char *perms = NULL; 98*7c478bd9Sstevel@tonic-gate char *aliases = 0; 99*7c478bd9Sstevel@tonic-gate char *basedir = NULL; 100*7c478bd9Sstevel@tonic-gate char *policy = NULL; 101*7c478bd9Sstevel@tonic-gate char *priv = NULL; 102*7c478bd9Sstevel@tonic-gate char *driver_name; 103*7c478bd9Sstevel@tonic-gate int found; 104*7c478bd9Sstevel@tonic-gate major_t major_num; 105*7c478bd9Sstevel@tonic-gate int rval; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 108*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 109*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 110*7c478bd9Sstevel@tonic-gate #endif 111*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate /* must be run by root */ 114*7c478bd9Sstevel@tonic-gate if (getuid() != 0) { 115*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NOT_ROOT)); 116*7c478bd9Sstevel@tonic-gate exit(1); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, "m:i:b:p:adlfuvP:")) != EOF) { 120*7c478bd9Sstevel@tonic-gate switch (opt) { 121*7c478bd9Sstevel@tonic-gate case 'a': 122*7c478bd9Sstevel@tonic-gate a_flag++; 123*7c478bd9Sstevel@tonic-gate break; 124*7c478bd9Sstevel@tonic-gate case 'b': 125*7c478bd9Sstevel@tonic-gate update_conf = 0; /* don't update .conf file */ 126*7c478bd9Sstevel@tonic-gate basedir = optarg; 127*7c478bd9Sstevel@tonic-gate break; 128*7c478bd9Sstevel@tonic-gate case 'd': 129*7c478bd9Sstevel@tonic-gate d_flag++; 130*7c478bd9Sstevel@tonic-gate break; 131*7c478bd9Sstevel@tonic-gate case 'f': 132*7c478bd9Sstevel@tonic-gate force_flag++; 133*7c478bd9Sstevel@tonic-gate break; 134*7c478bd9Sstevel@tonic-gate case 'i': 135*7c478bd9Sstevel@tonic-gate i_flag++; 136*7c478bd9Sstevel@tonic-gate aliases = optarg; 137*7c478bd9Sstevel@tonic-gate if (check_space_within_quote(aliases) == ERROR) { 138*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NO_SPACE), 139*7c478bd9Sstevel@tonic-gate aliases); 140*7c478bd9Sstevel@tonic-gate exit(1); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate break; 143*7c478bd9Sstevel@tonic-gate case 'l': /* private option */ 144*7c478bd9Sstevel@tonic-gate l_flag++; 145*7c478bd9Sstevel@tonic-gate break; 146*7c478bd9Sstevel@tonic-gate case 'm': 147*7c478bd9Sstevel@tonic-gate m_flag++; 148*7c478bd9Sstevel@tonic-gate perms = optarg; 149*7c478bd9Sstevel@tonic-gate break; 150*7c478bd9Sstevel@tonic-gate case 'p': 151*7c478bd9Sstevel@tonic-gate policy = optarg; 152*7c478bd9Sstevel@tonic-gate break; 153*7c478bd9Sstevel@tonic-gate case 'v': 154*7c478bd9Sstevel@tonic-gate verbose_flag++; 155*7c478bd9Sstevel@tonic-gate break; 156*7c478bd9Sstevel@tonic-gate case 'P': 157*7c478bd9Sstevel@tonic-gate priv = optarg; 158*7c478bd9Sstevel@tonic-gate break; 159*7c478bd9Sstevel@tonic-gate case '?' : 160*7c478bd9Sstevel@tonic-gate default: 161*7c478bd9Sstevel@tonic-gate usage(); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate /* 166*7c478bd9Sstevel@tonic-gate * check for flags and extra args 167*7c478bd9Sstevel@tonic-gate */ 168*7c478bd9Sstevel@tonic-gate if ((argv[optind] == NULL) || (optind + 1 != argc)) { 169*7c478bd9Sstevel@tonic-gate usage(); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * - cannot be adding and removing at the same time 174*7c478bd9Sstevel@tonic-gate * - if -a or -d is specified, it's an error if none of 175*7c478bd9Sstevel@tonic-gate * -i/-m/-p/-P is specified. 176*7c478bd9Sstevel@tonic-gate */ 177*7c478bd9Sstevel@tonic-gate if ((a_flag && d_flag) || 178*7c478bd9Sstevel@tonic-gate ((a_flag || d_flag) && 179*7c478bd9Sstevel@tonic-gate !m_flag && !i_flag && priv == NULL && policy == NULL)) { 180*7c478bd9Sstevel@tonic-gate usage(); 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* 184*7c478bd9Sstevel@tonic-gate * - with -d option or -a option either -i 'identify_name', 185*7c478bd9Sstevel@tonic-gate * -m 'permission', -p 'policy' or -P 'priv' should be specified 186*7c478bd9Sstevel@tonic-gate */ 187*7c478bd9Sstevel@tonic-gate if (m_flag || i_flag || policy != NULL || priv != NULL) { 188*7c478bd9Sstevel@tonic-gate if (!(a_flag || d_flag)) 189*7c478bd9Sstevel@tonic-gate usage(); 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate driver_name = argv[optind]; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate /* set up update_drv filenames */ 195*7c478bd9Sstevel@tonic-gate if ((build_filenames(basedir)) == ERROR) { 196*7c478bd9Sstevel@tonic-gate exit(1); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* no lock is needed for listing minor perm entry */ 200*7c478bd9Sstevel@tonic-gate if (l_flag) { 201*7c478bd9Sstevel@tonic-gate list_entry(minor_perm, driver_name, ":"); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate return (NOERR); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* must be only running version of add_drv/update_drv/rem_drv */ 207*7c478bd9Sstevel@tonic-gate enter_lock(); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate if ((check_perms_aliases(m_flag, i_flag)) == ERROR) { 210*7c478bd9Sstevel@tonic-gate err_exit(); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* update_drv doesn't modify /etc/name_to_major file */ 214*7c478bd9Sstevel@tonic-gate if ((check_name_to_major(R_OK)) == ERROR) 215*7c478bd9Sstevel@tonic-gate err_exit(); 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate if (priv != NULL && check_priv_entry(priv, a_flag) != 0) 218*7c478bd9Sstevel@tonic-gate err_exit(); 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate if (policy != NULL && (policy = check_plcy_entry(policy, driver_name, 221*7c478bd9Sstevel@tonic-gate d_flag ? B_TRUE : B_FALSE)) == NULL) 222*7c478bd9Sstevel@tonic-gate err_exit(); 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * ADD: -a option 226*7c478bd9Sstevel@tonic-gate * i_flag: update /etc/driver_aliases 227*7c478bd9Sstevel@tonic-gate * m_flag: update /etc/minor_perm 228*7c478bd9Sstevel@tonic-gate * -p: update /etc/security/device_policy 229*7c478bd9Sstevel@tonic-gate * -P: update /etc/security/extra_privs 230*7c478bd9Sstevel@tonic-gate * if force_flag is specified continue w/ the next operation 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate if (a_flag) { 233*7c478bd9Sstevel@tonic-gate if (m_flag) { 234*7c478bd9Sstevel@tonic-gate /* check if the permissions are valid */ 235*7c478bd9Sstevel@tonic-gate if ((error = check_perm_opts(perms)) == ERROR) { 236*7c478bd9Sstevel@tonic-gate if (force_flag == 0) { /* no force flag */ 237*7c478bd9Sstevel@tonic-gate exit_unlock(); 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate return (error); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* 244*7c478bd9Sstevel@tonic-gate * update the file, if and only if 245*7c478bd9Sstevel@tonic-gate * we didn't run into error earlier. 246*7c478bd9Sstevel@tonic-gate */ 247*7c478bd9Sstevel@tonic-gate if ((error != ERROR) && 248*7c478bd9Sstevel@tonic-gate (error = update_minor_entry(driver_name, perms))) { 249*7c478bd9Sstevel@tonic-gate if (force_flag == 0) { /* no force flag */ 250*7c478bd9Sstevel@tonic-gate exit_unlock(); 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate return (error); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate cleanup_flag |= CLEAN_NAM_MAJ; 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * Notify running system of minor perm change 259*7c478bd9Sstevel@tonic-gate */ 260*7c478bd9Sstevel@tonic-gate if (basedir == NULL || (strcmp(basedir, "/") == 0)) { 261*7c478bd9Sstevel@tonic-gate rval = devfs_add_minor_perm(driver_name, 262*7c478bd9Sstevel@tonic-gate log_minorperm_error); 263*7c478bd9Sstevel@tonic-gate if (rval) { 264*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 265*7c478bd9Sstevel@tonic-gate gettext(ERR_UPDATE_PERM), 266*7c478bd9Sstevel@tonic-gate driver_name); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate if (priv != NULL) { 272*7c478bd9Sstevel@tonic-gate (void) append_to_file(driver_name, priv, extra_privs, 273*7c478bd9Sstevel@tonic-gate ',', ":"); 274*7c478bd9Sstevel@tonic-gate cleanup_flag |= CLEAN_DRV_PRIV; 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if (policy != NULL) { 278*7c478bd9Sstevel@tonic-gate if ((error = update_device_policy(device_policy, 279*7c478bd9Sstevel@tonic-gate policy, B_TRUE)) != 0) { 280*7c478bd9Sstevel@tonic-gate exit_unlock(); 281*7c478bd9Sstevel@tonic-gate return (error); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate cleanup_flag |= CLEAN_DEV_POLICY; 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate if (i_flag) { 287*7c478bd9Sstevel@tonic-gate /* check if the alias is unique */ 288*7c478bd9Sstevel@tonic-gate if ((error = aliases_unique(aliases)) == ERROR) { 289*7c478bd9Sstevel@tonic-gate exit_unlock(); 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate return (error); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate /* update the file */ 295*7c478bd9Sstevel@tonic-gate if ((error = update_driver_aliases(driver_name, 296*7c478bd9Sstevel@tonic-gate aliases)) == ERROR) { 297*7c478bd9Sstevel@tonic-gate exit_unlock(); 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate return (error); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate found = get_major_no(driver_name, name_to_major); 303*7c478bd9Sstevel@tonic-gate if (found == ERROR) { 304*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_MAX_MAJOR), 305*7c478bd9Sstevel@tonic-gate name_to_major); 306*7c478bd9Sstevel@tonic-gate err_exit(); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate if (found == UNIQUE) { 310*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 311*7c478bd9Sstevel@tonic-gate gettext(ERR_NOT_INSTALLED), driver_name); 312*7c478bd9Sstevel@tonic-gate err_exit(); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate major_num = (major_t)found; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /* paranoia - if we crash whilst configuring */ 318*7c478bd9Sstevel@tonic-gate sync(); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate cleanup_flag |= CLEAN_DRV_ALIAS; 321*7c478bd9Sstevel@tonic-gate if (config_driver(driver_name, major_num, aliases, NULL, 322*7c478bd9Sstevel@tonic-gate cleanup_flag, verbose_flag) == ERROR) { 323*7c478bd9Sstevel@tonic-gate err_exit(); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate if (update_conf && (i_flag || policy != NULL)) 328*7c478bd9Sstevel@tonic-gate /* load the driver */ 329*7c478bd9Sstevel@tonic-gate load_driver(driver_name, verbose_flag); 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate exit_unlock(); 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate return (0); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate /* 338*7c478bd9Sstevel@tonic-gate * DELETE: -d option 339*7c478bd9Sstevel@tonic-gate * i_flag: update /etc/driver_aliases 340*7c478bd9Sstevel@tonic-gate * m_flag: update /etc/minor_perm 341*7c478bd9Sstevel@tonic-gate * -p: update /etc/security/device_policy 342*7c478bd9Sstevel@tonic-gate * -P: update /etc/security/extra_privs 343*7c478bd9Sstevel@tonic-gate */ 344*7c478bd9Sstevel@tonic-gate if (d_flag) { 345*7c478bd9Sstevel@tonic-gate int err = NOERR; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate if (m_flag) { 348*7c478bd9Sstevel@tonic-gate /* 349*7c478bd9Sstevel@tonic-gate * On a running system, we first need to 350*7c478bd9Sstevel@tonic-gate * remove devfs's idea of the minor perms. 351*7c478bd9Sstevel@tonic-gate * We don't have any ability to do this singly 352*7c478bd9Sstevel@tonic-gate * at this point. 353*7c478bd9Sstevel@tonic-gate */ 354*7c478bd9Sstevel@tonic-gate if (basedir == NULL || (strcmp(basedir, "/") == 0)) { 355*7c478bd9Sstevel@tonic-gate rval = devfs_rm_minor_perm(driver_name, 356*7c478bd9Sstevel@tonic-gate log_minorperm_error); 357*7c478bd9Sstevel@tonic-gate if (rval) { 358*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 359*7c478bd9Sstevel@tonic-gate gettext(ERR_UPDATE_PERM), 360*7c478bd9Sstevel@tonic-gate driver_name); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate if ((error = delete_entry(minor_perm, 365*7c478bd9Sstevel@tonic-gate driver_name, ":", perms)) != NOERR) { 366*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NO_ENTRY), 367*7c478bd9Sstevel@tonic-gate driver_name, minor_perm); 368*7c478bd9Sstevel@tonic-gate err = error; 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate /* 371*7c478bd9Sstevel@tonic-gate * Notify running system of new minor perm state 372*7c478bd9Sstevel@tonic-gate */ 373*7c478bd9Sstevel@tonic-gate if (basedir == NULL || (strcmp(basedir, "/") == 0)) { 374*7c478bd9Sstevel@tonic-gate rval = devfs_add_minor_perm(driver_name, 375*7c478bd9Sstevel@tonic-gate log_minorperm_error); 376*7c478bd9Sstevel@tonic-gate if (rval) { 377*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 378*7c478bd9Sstevel@tonic-gate gettext(ERR_UPDATE_PERM), 379*7c478bd9Sstevel@tonic-gate driver_name); 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate if (i_flag) { 385*7c478bd9Sstevel@tonic-gate if ((error = delete_entry(driver_aliases, 386*7c478bd9Sstevel@tonic-gate driver_name, ":", aliases)) != NOERR) { 387*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NO_ENTRY), 388*7c478bd9Sstevel@tonic-gate driver_name, driver_aliases); 389*7c478bd9Sstevel@tonic-gate if (err != NOERR) 390*7c478bd9Sstevel@tonic-gate err = error; 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate if (priv != NULL) { 395*7c478bd9Sstevel@tonic-gate if ((error = delete_entry(extra_privs, driver_name, ":", 396*7c478bd9Sstevel@tonic-gate priv)) != NOERR) { 397*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NO_ENTRY), 398*7c478bd9Sstevel@tonic-gate driver_name, extra_privs); 399*7c478bd9Sstevel@tonic-gate if (err != NOERR) 400*7c478bd9Sstevel@tonic-gate err = error; 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate if (policy != NULL) { 405*7c478bd9Sstevel@tonic-gate if ((error = delete_plcy_entry(device_policy, 406*7c478bd9Sstevel@tonic-gate policy)) != NOERR) { 407*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_NO_ENTRY), 408*7c478bd9Sstevel@tonic-gate driver_name, device_policy); 409*7c478bd9Sstevel@tonic-gate if (err != NOERR) 410*7c478bd9Sstevel@tonic-gate err = error; 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate if (err == NOERR && update_conf) { 415*7c478bd9Sstevel@tonic-gate if (i_flag || m_flag) { 416*7c478bd9Sstevel@tonic-gate /* try to unload the driver */ 417*7c478bd9Sstevel@tonic-gate (void) unload_drv(driver_name, 418*7c478bd9Sstevel@tonic-gate force_flag, verbose_flag); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate /* reload the policy */ 421*7c478bd9Sstevel@tonic-gate if (policy != NULL) 422*7c478bd9Sstevel@tonic-gate load_driver(driver_name, verbose_flag); 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate exit_unlock(); 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate return (err); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* driver name must exist (for update_conf stuff) */ 430*7c478bd9Sstevel@tonic-gate major = get_major_no(driver_name, name_to_major); 431*7c478bd9Sstevel@tonic-gate if (major == ERROR) { 432*7c478bd9Sstevel@tonic-gate err_exit(); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate /* 436*7c478bd9Sstevel@tonic-gate * Update driver.conf file: 437*7c478bd9Sstevel@tonic-gate * First try to unload driver module. If it fails, there may 438*7c478bd9Sstevel@tonic-gate * be attached devices using the old driver.conf properties, 439*7c478bd9Sstevel@tonic-gate * so we cannot safely update driver.conf 440*7c478bd9Sstevel@tonic-gate * 441*7c478bd9Sstevel@tonic-gate * The user may specify -f to force a driver.conf update. 442*7c478bd9Sstevel@tonic-gate * In this case, we will update driver.conf cache. All attached 443*7c478bd9Sstevel@tonic-gate * devices still reference old driver.conf properties, including 444*7c478bd9Sstevel@tonic-gate * driver global properties. Devices attached in the future will 445*7c478bd9Sstevel@tonic-gate * referent properties in the updated driver.conf file. 446*7c478bd9Sstevel@tonic-gate */ 447*7c478bd9Sstevel@tonic-gate if (update_conf) { 448*7c478bd9Sstevel@tonic-gate (void) unload_drv(driver_name, force_flag, verbose_flag); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate if ((modctl(MODUNLOADDRVCONF, major) != 0) || 451*7c478bd9Sstevel@tonic-gate (modctl(MODLOADDRVCONF, major) != 0)) { 452*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(ERR_DRVCONF), 453*7c478bd9Sstevel@tonic-gate driver_name); 454*7c478bd9Sstevel@tonic-gate err_exit(); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate if (verbose_flag) { 458*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(DRVCONF_UPDATED), 459*7c478bd9Sstevel@tonic-gate driver_name); 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate /* rebuild /devices & /dev */ 464*7c478bd9Sstevel@tonic-gate load_driver(driver_name, verbose_flag); 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate exit_unlock(); 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate return (NOERR); 469*7c478bd9Sstevel@tonic-gate } 470