4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
32 * Manages mapping between a security principal name and unix uid
45 get_der_length(unsigned char **, unsigned int, unsigned int *);
48 der_length_size(unsigned int);
51 put_der_length(unsigned int, unsigned char **, unsigned int);
56 * GSS export name constants
58 static const char *expNameTokId
= "\x04\x01";
59 static const int expNameTokIdLen
= 2;
60 static const int mechOidLenLen
= 2;
61 static const int mechOidTagLen
= 1;
65 * Internal utility routines.
69 * gsscred_read_config_file
71 * function to read the optional gsscred configuration file
72 * which specifies which backend to use to store the gsscred
75 * we now only support flat files (btw, this file for backend is Obsoleted
79 gsscred_read_config_file(void)
81 return (GSSCRED_FLAT_FILE
);
82 } /* gsscred_read_config_file */
88 * construct a principal name in the GSS_C_NT_EXPORT_NAME format.
90 int gsscred_MakeName(const gss_OID mechOid
, const char *name
,
91 const char *nameOidStr
, gss_buffer_t nameOut
)
95 OM_uint32 minor
, major
;
96 gss_buffer_desc aName
= GSS_C_EMPTY_BUFFER
, oidStr
;
99 nameOut
->value
= NULL
;
101 /* we need to import the name, then canonicalize it, then export it */
102 if (nameOidStr
== NULL
)
103 nameOid
= (gss_OID
)GSS_C_NT_USER_NAME
;
105 oidStr
.length
= strlen(nameOidStr
);
106 oidStr
.value
= (void *)nameOidStr
;
107 if (gss_str_to_oid(&minor
, &oidStr
, &nameOid
) !=
109 (void) fprintf(stderr
,
110 gettext("\nInvalid name oid supplied [%s].\n"),
116 /* first import the name */
117 aName
.length
= strlen(name
);
118 aName
.value
= (void*)name
;
119 major
= gss_import_name(&minor
, &aName
, nameOid
, &intName
);
120 if (nameOidStr
!= NULL
) {
121 free(nameOid
->elements
);
125 if (major
!= GSS_S_COMPLETE
) {
126 (void) fprintf(stderr
,
127 gettext("\nInternal error importing name [%s].\n"),
132 /* now canonicalize the name */
133 if (gss_canonicalize_name(&minor
, intName
, mechOid
, NULL
)
135 (void) fprintf(stderr
,
136 gettext("\nInternal error canonicalizing name"
139 (void) gss_release_name(&minor
, &intName
);
143 /* now convert to export format */
144 if (gss_export_name(&minor
, intName
, nameOut
) != GSS_S_COMPLETE
) {
145 (void) fprintf(stderr
,
146 gettext("\nInternal error exporting name [%s].\n"),
148 (void) gss_release_name(&minor
, &intName
);
152 (void) gss_release_name(&minor
, &intName
);
154 } /* ******* makeName ****** */
158 * Constructs a part of the GSS_NT_EXPORT_NAME
159 * Only the mechanism independent name part is created.
162 gsscred_MakeNameHeader(const gss_OID mechOid
, gss_buffer_t outNameHdr
)
164 unsigned char *buf
= NULL
;
165 int mechOidDERLength
, mechOidLength
;
167 /* determine the length of buffer needed */
168 mechOidDERLength
= der_length_size(mechOid
->length
);
169 outNameHdr
->length
= mechOidLenLen
+ mechOidTagLen
+
170 mechOidDERLength
+ expNameTokIdLen
+ mechOid
->length
;
171 if ((outNameHdr
->value
= (void*)malloc(outNameHdr
->length
)) == NULL
) {
172 outNameHdr
->length
= 0;
176 /* start by putting the token id */
177 buf
= (unsigned char *) outNameHdr
->value
;
178 (void) memset(outNameHdr
->value
, '\0', outNameHdr
->length
);
179 (void) memcpy(buf
, expNameTokId
, expNameTokIdLen
);
180 buf
+= expNameTokIdLen
;
183 * next 2 bytes contain the mech oid length (includes
186 mechOidLength
= mechOidTagLen
+ mechOidDERLength
+
189 *buf
++ = (mechOidLength
& 0xFF00) >> 8;
190 *buf
++ = (mechOidLength
& 0x00FF);
192 if (put_der_length(mechOid
->length
, &buf
,
193 mechOidDERLength
) != 0) {
194 /* free the buffer */
195 free(outNameHdr
->value
);
199 /* now add the mechanism oid */
200 (void) memcpy(buf
, mechOid
->elements
, mechOid
->length
);
202 /* we stop here because the rest is mechanism specific */
204 } /* gsscred_MakeNameHeader */
208 * Converts the supplied string to HEX.
209 * The passed in buffer must be twice as long as the input buffer.
210 * Long form is used (i.e. '\0' will become '00'). This is needed
211 * to enable proper re-parsing of names.
214 gsscred_AsHex(gss_buffer_t dataIn
, gss_buffer_t dataOut
)
220 if (dataOut
->length
< ((dataIn
->length
*2) + 1))
223 out
= (char *)dataOut
->value
;
224 in
= (char *)dataIn
->value
;
227 for (i
= 0; i
< dataIn
->length
; i
++) {
228 tmp
= (unsigned int)(*in
++)&0xff;
229 (void) sprintf(out
, "%02X", tmp
);
233 dataOut
->length
= out
- (char *)dataOut
->value
;
237 } /* ******* gsscred_AsHex ******* */
241 * GSS entry point for retrieving user uid mappings.
242 * The name buffer contains a principal name in exported format.
245 gss_getGssCredEntry(const gss_buffer_t expName
, uid_t
*uid
)
249 gss_buffer_desc mechOidDesc
= GSS_C_EMPTY_BUFFER
,
250 mechHexOidDesc
= GSS_C_EMPTY_BUFFER
,
251 expNameHexDesc
= GSS_C_EMPTY_BUFFER
;
252 char oidHexBuf
[256], expNameHexBuf
[1024];
256 tableSource
= gsscred_read_config_file();
259 * for xfn (ldap?), we must first construct, a hex mechansim oid string
261 if (expName
->length
< (expNameTokIdLen
+ mechOidLenLen
+
265 buf
= (unsigned char *)expName
->value
;
266 buf
+= expNameTokIdLen
;
268 /* skip oid length - get to der */
276 len
= get_der_length(&buf
,
277 (expName
->length
- expNameTokIdLen
278 - mechOidLenLen
- mechOidTagLen
), &dummy
);
282 mechOidDesc
.length
= len
;
284 if (expName
->length
<
285 (expNameTokIdLen
+ mechOidLenLen
+ mechOidDesc
.length
286 + dummy
+ mechOidTagLen
))
289 mechOidDesc
.value
= (void *)buf
;
291 /* convert the oid buffer to hex */
292 mechHexOidDesc
.value
= (void*) oidHexBuf
;
293 mechHexOidDesc
.length
= sizeof (oidHexBuf
);
294 if (!gsscred_AsHex(&mechOidDesc
, &mechHexOidDesc
))
297 /* also need to convert the name buffer into hex */
298 expNameHexDesc
.value
= expNameHexBuf
;
299 expNameHexDesc
.length
= sizeof (expNameHexBuf
);
300 if (!gsscred_AsHex(expName
, &expNameHexDesc
))
303 if (tableSource
== GSSCRED_FLAT_FILE
)
304 return (file_getGssCredUid(&expNameHexDesc
, uid
));
306 return (0); /* XXX for new backends (ldap, dss), 0->1 probably */
307 } /* gss_getGssCredEntry */