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 2007 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 idmap_reg_t *reg; 51 int err; 52 53 idmap_get_door(®, &dh); 54 55 if (reg == NULL || dh == NULL) 56 return (set_errno(EPERM)); 57 58 if ((err = door_ki_info(dh, &di)) != 0) 59 return (set_errno(err)); 60 61 if (curproc->p_pid != di.di_target) 62 return (set_errno(EPERM)); 63 64 idmap_release_door(reg); 65 66 if (nuids < 0 || ngids < 0) 67 return (set_errno(EINVAL)); 68 69 if (flag != 0 || nuids > 0) 70 err = eph_uid_alloc(flag, &su, nuids); 71 if (err == 0 && (flag != 0 || ngids > 0)) 72 err = eph_gid_alloc(flag, &sg, ngids); 73 74 if (err != 0) 75 return (set_errno(EOVERFLOW)); 76 77 r.r_val1 = su; 78 r.r_val2 = sg; 79 return (r.r_vals); 80 } 81 82 static int 83 idmap_reg(int did) 84 { 85 door_handle_t dh; 86 int err; 87 88 if ((err = secpolicy_idmap(CRED())) != 0) 89 return (set_errno(err)); 90 91 dh = door_ki_lookup(did); 92 93 if (dh == NULL) 94 return (set_errno(EBADF)); 95 96 err = idmap_reg_dh(dh); 97 98 return (err); 99 } 100 101 static int 102 idmap_unreg(int did) 103 { 104 door_handle_t dh = door_ki_lookup(did); 105 int res; 106 107 if (dh == NULL) 108 return (set_errno(EINVAL)); 109 110 res = idmap_unreg_dh(dh); 111 door_ki_rele(dh); 112 113 if (res != 0) 114 return (set_errno(res)); 115 return (0); 116 } 117 118 uint64_t 119 sidsys(int op, int flag, int nuids, int ngids) 120 { 121 switch (op) { 122 case SIDSYS_ALLOC_IDS: 123 return (allocids(flag, nuids, ngids)); 124 case SIDSYS_IDMAP_REG: 125 return (idmap_reg(flag)); 126 case SIDSYS_IDMAP_UNREG: 127 return (idmap_unreg(flag)); 128 default: 129 return (set_errno(EINVAL)); 130 } 131 } 132