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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This is an extract from usr/src/common/smbsrv/smb_sid.c, 28 * with functions renamed as part of a tentative plan for convergence. 29 */ 30 #ifndef _KERNEL 31 #include <stdio.h> 32 #include <strings.h> 33 #include <stdlib.h> 34 #include <syslog.h> 35 #else /* _KERNEL */ 36 #include <sys/types.h> 37 #include <sys/sunddi.h> 38 #endif /* _KERNEL */ 39 40 #include <sidutil.h> 41 42 /* 43 * sid_len 44 * 45 * Returns the number of bytes required to hold the sid. 46 */ 47 int 48 sid_len(sid_t *sid) 49 { 50 if (sid == NULL) 51 return (0); 52 53 return (sizeof (sid_t) - sizeof (uint32_t) 54 + (sid->sid_subauthcnt * sizeof (uint32_t))); 55 } 56 57 /* 58 * sid_tostr 59 * 60 * Fill in the passed buffer with the string form of the given 61 * binary sid. 62 */ 63 void 64 sid_tostr(sid_t *sid, char *strsid) 65 { 66 char *p = strsid; 67 int i; 68 69 if (sid == NULL || strsid == NULL) 70 return; 71 72 (void) sprintf(p, "S-%d-", sid->sid_revision); 73 while (*p) 74 p++; 75 76 for (i = 0; i < NT_SID_AUTH_MAX; ++i) { 77 if (sid->sid_authority[i] != 0 || i == NT_SID_AUTH_MAX - 1) { 78 (void) sprintf(p, "%d", sid->sid_authority[i]); 79 while (*p) 80 p++; 81 } 82 } 83 84 for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) { 85 (void) sprintf(p, "-%u", sid->sid_subauth[i]); 86 while (*p) 87 p++; 88 } 89 } 90 91 /* 92 * sid_fromstr 93 * 94 * Converts a SID in string form to a SID structure. There are lots of 95 * simplifying assumptions in here. The memory for the SID is allocated 96 * as if it was the largest possible SID; the caller is responsible for 97 * freeing the memory when it is no longer required. We assume that the 98 * string starts with "S-1-" and that the authority is held in the last 99 * byte, which should be okay for most situations. It also assumes the 100 * sub-authorities are in decimal format. 101 * 102 * On success, a pointer to a SID is returned. Otherwise a null pointer 103 * is returned. 104 */ 105 sid_t * 106 sid_fromstr(char *sidstr) 107 { 108 sid_t *sid; 109 char *p; 110 int size; 111 uint8_t i; 112 113 if (sidstr == NULL) 114 return (NULL); 115 116 if (strncmp(sidstr, "S-1-", 4) != 0) 117 return (NULL); 118 119 size = sizeof (sid_t) + (NT_SID_SUBAUTH_MAX * sizeof (uint32_t)); 120 121 if ((sid = malloc(size)) == NULL) 122 return (NULL); 123 124 bzero(sid, size); 125 sid->sid_revision = NT_SID_REVISION; 126 sid->sid_authority[5] = atoi(&sidstr[4]); 127 128 for (i = 0, p = &sidstr[5]; i < NT_SID_SUBAUTH_MAX && *p; ++i) { 129 while (*p && *p == '-') 130 ++p; 131 132 if (*p < '0' || *p > '9') { 133 free(sid); 134 return (NULL); 135 } 136 137 sid->sid_subauth[i] = strtoul(p, NULL, 10); 138 139 while (*p && *p != '-') 140 ++p; 141 } 142 143 sid->sid_subauthcnt = i; 144 return (sid); 145 } 146 147 void 148 sid_free(sid_t *sid) 149 { 150 #ifdef _KERNEL 151 if (sid == NULL) 152 return; 153 154 kmem_free(sid, sid_len(sid)); 155 #else 156 free(sid); 157 #endif 158 } 159 160 void 161 sid_to_le(sid_t *sid) 162 { 163 int i; 164 165 for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) { 166 uint32_t v = sid->sid_subauth[i]; 167 uint8_t *p = (uint8_t *)&sid->sid_subauth[i]; 168 169 p[0] = v & 0xff; 170 p[1] = (v >> 8) & 0xff; 171 p[2] = (v >> 16) & 0xff; 172 p[3] = (v >> 24) & 0xff; 173 } 174 } 175 176 void 177 sid_from_le(sid_t *sid) 178 { 179 int i; 180 181 for (i = 0; i < sid->sid_subauthcnt && i < NT_SID_SUBAUTH_MAX; ++i) { 182 uint32_t v; 183 uint8_t *p = (uint8_t *)&sid->sid_subauth[i]; 184 185 v = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 186 187 sid->sid_subauth[i] = v; 188 } 189 } 190