1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * SID system call. 31 */ 32 33 #include <sys/sid.h> 34 #include <sys/cred.h> 35 #include <sys/errno.h> 36 #include <sys/systm.h> 37 #include <sys/policy.h> 38 #include <sys/door.h> 39 #include <sys/kidmap.h> 40 #include <sys/proc.h> 41 42 static uint64_t 43 allocids(int flag, int nuids, int ngids) 44 { 45 rval_t r; 46 uid_t su = 0; 47 gid_t sg = 0; 48 struct door_info di; 49 door_handle_t dh; 50 int err; 51 zone_t *zone = crgetzone(CRED()); 52 53 dh = idmap_get_door(zone); 54 55 if (dh == NULL) 56 return (set_errno(EPERM)); 57 58 if ((err = door_ki_info(dh, &di)) != 0) { 59 door_ki_rele(dh); 60 return (set_errno(err)); 61 } 62 63 door_ki_rele(dh); 64 65 if (curproc->p_pid != di.di_target) 66 return (set_errno(EPERM)); 67 68 if (flag) 69 idmap_purge_cache(zone); 70 71 if (nuids < 0 || ngids < 0) 72 return (set_errno(EINVAL)); 73 74 if (flag != 0 || nuids > 0) 75 err = eph_uid_alloc(zone, flag, &su, nuids); 76 if (err == 0 && (flag != 0 || ngids > 0)) 77 err = eph_gid_alloc(zone, flag, &sg, ngids); 78 79 if (err != 0) 80 return (set_errno(EOVERFLOW)); 81 82 r.r_val1 = su; 83 r.r_val2 = sg; 84 return (r.r_vals); 85 } 86 87 static int 88 idmap_reg(int did) 89 { 90 door_handle_t dh; 91 int err; 92 cred_t *cr = CRED(); 93 94 if ((err = secpolicy_idmap(cr)) != 0) 95 return (set_errno(err)); 96 97 dh = door_ki_lookup(did); 98 99 if (dh == NULL) 100 return (set_errno(EBADF)); 101 102 if ((err = idmap_reg_dh(crgetzone(cr), dh)) != 0) 103 return (set_errno(err)); 104 105 return (0); 106 } 107 108 static int 109 idmap_unreg(int did) 110 { 111 door_handle_t dh = door_ki_lookup(did); 112 int res; 113 zone_t *zone; 114 115 if (dh == NULL) 116 return (set_errno(EINVAL)); 117 118 zone = crgetzone(CRED()); 119 res = idmap_unreg_dh(zone, dh); 120 door_ki_rele(dh); 121 122 if (res != 0) 123 return (set_errno(res)); 124 return (0); 125 } 126 127 uint64_t 128 sidsys(int op, int flag, int nuids, int ngids) 129 { 130 switch (op) { 131 case SIDSYS_ALLOC_IDS: 132 return (allocids(flag, nuids, ngids)); 133 case SIDSYS_IDMAP_REG: 134 return (idmap_reg(flag)); 135 case SIDSYS_IDMAP_UNREG: 136 return (idmap_unreg(flag)); 137 default: 138 return (set_errno(EINVAL)); 139 } 140 } 141