Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Winbind client API
5 :
6 : Copyright (C) Gerald (Jerry) Carter 2007
7 : Copyright (C) Volker Lendecke 2010
8 :
9 :
10 : This library is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU Lesser General Public
12 : License as published by the Free Software Foundation; either
13 : version 3 of the License, or (at your option) any later version.
14 :
15 : This library is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 : Library General Public License for more details.
19 :
20 : You should have received a copy of the GNU Lesser General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : /* Required Headers */
25 :
26 : #include <stdio.h>
27 :
28 : #include "libwbclient.h"
29 :
30 : #define MAX(a, b) (((a) > (b)) ? (a) : (b))
31 :
32 : /* Convert a sid to a string into a buffer. Return the string
33 : * length. If buflen is too small, return the string length that would
34 : * result if it was long enough. */
35 0 : int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen)
36 : {
37 : uint64_t id_auth;
38 : int i, ofs;
39 :
40 0 : if (!sid) {
41 0 : strncpy(buf, "(NULL SID)", buflen);
42 0 : buf[buflen < 10 ? buflen :10] = '\0';
43 0 : return 10; /* strlen("(NULL SID)") */
44 : }
45 :
46 0 : id_auth = (uint64_t)sid->id_auth[5] +
47 0 : ((uint64_t)sid->id_auth[4] << 8) +
48 0 : ((uint64_t)sid->id_auth[3] << 16) +
49 0 : ((uint64_t)sid->id_auth[2] << 24) +
50 0 : ((uint64_t)sid->id_auth[1] << 32) +
51 0 : ((uint64_t)sid->id_auth[0] << 40);
52 :
53 0 : ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num);
54 0 : if (id_auth >= UINT32_MAX) {
55 0 : ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx",
56 : (unsigned long long)id_auth);
57 : } else {
58 0 : ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu",
59 : (unsigned long long)id_auth);
60 : }
61 :
62 0 : for (i = 0; i < sid->num_auths; i++) {
63 0 : ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u",
64 : (unsigned int)sid->sub_auths[i]);
65 : }
66 0 : return ofs;
67 : }
68 :
69 : /* Convert a binary SID to a character string */
70 0 : wbcErr wbcSidToString(const struct wbcDomainSid *sid,
71 : char **sid_string)
72 : {
73 : char buf[WBC_SID_STRING_BUFLEN];
74 : char *result;
75 : int len;
76 :
77 0 : if (!sid) {
78 0 : return WBC_ERR_INVALID_SID;
79 : }
80 :
81 0 : len = wbcSidToStringBuf(sid, buf, sizeof(buf));
82 :
83 0 : if (len+1 > sizeof(buf)) {
84 0 : return WBC_ERR_INVALID_SID;
85 : }
86 :
87 0 : result = (char *)wbcAllocateMemory(len+1, 1, NULL);
88 0 : if (result == NULL) {
89 0 : return WBC_ERR_NO_MEMORY;
90 : }
91 0 : memcpy(result, buf, len+1);
92 :
93 0 : *sid_string = result;
94 0 : return WBC_ERR_SUCCESS;
95 : }
96 :
97 : #define AUTHORITY_MASK (~(0xffffffffffffULL))
98 :
99 : /* Convert a character string to a binary SID */
100 0 : wbcErr wbcStringToSid(const char *str,
101 : struct wbcDomainSid *sid)
102 : {
103 : const char *p;
104 : char *q;
105 : uint64_t x;
106 0 : wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
107 :
108 0 : if (!sid) {
109 0 : wbc_status = WBC_ERR_INVALID_PARAM;
110 0 : BAIL_ON_WBC_ERROR(wbc_status);
111 : }
112 :
113 : /* Sanity check for either "S-" or "s-" */
114 :
115 0 : if (!str
116 0 : || (str[0]!='S' && str[0]!='s')
117 0 : || (str[1]!='-'))
118 : {
119 0 : wbc_status = WBC_ERR_INVALID_PARAM;
120 0 : BAIL_ON_WBC_ERROR(wbc_status);
121 : }
122 :
123 : /* Get the SID revision number */
124 :
125 0 : p = str+2;
126 0 : x = (uint64_t)strtoul(p, &q, 10);
127 0 : if (x==0 || x > UINT8_MAX || !q || *q!='-') {
128 0 : wbc_status = WBC_ERR_INVALID_SID;
129 0 : BAIL_ON_WBC_ERROR(wbc_status);
130 : }
131 0 : sid->sid_rev_num = (uint8_t)x;
132 :
133 : /*
134 : * Next the Identifier Authority. This is stored big-endian in a
135 : * 6 byte array. If the authority value is >= UINT_MAX, then it should
136 : * be expressed as a hex value, according to MS-DTYP.
137 : */
138 0 : p = q+1;
139 0 : x = strtoull(p, &q, 0);
140 0 : if (!q || *q!='-' || (x & AUTHORITY_MASK)) {
141 0 : wbc_status = WBC_ERR_INVALID_SID;
142 0 : BAIL_ON_WBC_ERROR(wbc_status);
143 : }
144 0 : sid->id_auth[5] = (x & 0x0000000000ffULL);
145 0 : sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8;
146 0 : sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16;
147 0 : sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24;
148 0 : sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32;
149 0 : sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40;
150 :
151 : /* now read the subauthorities */
152 0 : p = q +1;
153 0 : sid->num_auths = 0;
154 0 : while (sid->num_auths < WBC_MAXSUBAUTHS) {
155 0 : x = strtoull(p, &q, 10);
156 0 : if (p == q)
157 0 : break;
158 0 : if (x > UINT32_MAX) {
159 0 : wbc_status = WBC_ERR_INVALID_SID;
160 0 : BAIL_ON_WBC_ERROR(wbc_status);
161 : }
162 0 : sid->sub_auths[sid->num_auths++] = x;
163 :
164 0 : if (*q != '-') {
165 0 : break;
166 : }
167 0 : p = q + 1;
168 : }
169 :
170 : /* IF we ended early, then the SID could not be converted */
171 :
172 0 : if (q && *q!='\0') {
173 0 : wbc_status = WBC_ERR_INVALID_SID;
174 0 : BAIL_ON_WBC_ERROR(wbc_status);
175 : }
176 :
177 0 : wbc_status = WBC_ERR_SUCCESS;
178 :
179 : done:
180 0 : return wbc_status;
181 :
182 : }
183 :
184 0 : const char* wbcSidTypeString(enum wbcSidType type)
185 : {
186 0 : switch (type) {
187 0 : case WBC_SID_NAME_USE_NONE: return "SID_NONE";
188 0 : case WBC_SID_NAME_USER: return "SID_USER";
189 0 : case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP";
190 0 : case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN";
191 0 : case WBC_SID_NAME_ALIAS: return "SID_ALIAS";
192 0 : case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP";
193 0 : case WBC_SID_NAME_DELETED: return "SID_DELETED";
194 0 : case WBC_SID_NAME_INVALID: return "SID_INVALID";
195 0 : case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN";
196 0 : case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER";
197 0 : default: return "Unknown type";
198 : }
199 : }
|