17c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27c478bd9Sstevel@tonic-gate 37c478bd9Sstevel@tonic-gate /* 47c478bd9Sstevel@tonic-gate * Copyright 1993 by OpenVision Technologies, Inc. 5*ab9b2e15Sgtb * 67c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, distribute, and sell this software 77c478bd9Sstevel@tonic-gate * and its documentation for any purpose is hereby granted without fee, 87c478bd9Sstevel@tonic-gate * provided that the above copyright notice appears in all copies and 97c478bd9Sstevel@tonic-gate * that both that copyright notice and this permission notice appear in 107c478bd9Sstevel@tonic-gate * supporting documentation, and that the name of OpenVision not be used 117c478bd9Sstevel@tonic-gate * in advertising or publicity pertaining to distribution of the software 127c478bd9Sstevel@tonic-gate * without specific, written prior permission. OpenVision makes no 137c478bd9Sstevel@tonic-gate * representations about the suitability of this software for any 147c478bd9Sstevel@tonic-gate * purpose. It is provided "as is" without express or implied warranty. 15*ab9b2e15Sgtb * 167c478bd9Sstevel@tonic-gate * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 177c478bd9Sstevel@tonic-gate * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 187c478bd9Sstevel@tonic-gate * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 197c478bd9Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 207c478bd9Sstevel@tonic-gate * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 217c478bd9Sstevel@tonic-gate * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 227c478bd9Sstevel@tonic-gate * PERFORMANCE OF THIS SOFTWARE. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 26*ab9b2e15Sgtb * $Id: import_name.c 18015 2006-05-17 05:26:12Z raeburn $ 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 29*ab9b2e15Sgtb #include "gssapiP_krb5.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #ifndef NO_PASSWORD 327c478bd9Sstevel@tonic-gate #include <pwd.h> 33*ab9b2e15Sgtb #include <stdio.h> 347c478bd9Sstevel@tonic-gate #endif 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #ifdef HAVE_STRING_H 377c478bd9Sstevel@tonic-gate #include <string.h> 387c478bd9Sstevel@tonic-gate #else 397c478bd9Sstevel@tonic-gate #include <strings.h> 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * errors: 447c478bd9Sstevel@tonic-gate * GSS_S_BAD_NAMETYPE if the type is bogus 457c478bd9Sstevel@tonic-gate * GSS_S_BAD_NAME if the type is good but the name is bogus 467c478bd9Sstevel@tonic-gate * GSS_S_FAILURE if memory allocation fails 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate OM_uint32 50*ab9b2e15Sgtb krb5_gss_import_name(minor_status, input_name_buffer, 517c478bd9Sstevel@tonic-gate input_name_type, output_name) 527c478bd9Sstevel@tonic-gate OM_uint32 *minor_status; 537c478bd9Sstevel@tonic-gate gss_buffer_t input_name_buffer; 547c478bd9Sstevel@tonic-gate gss_OID input_name_type; 557c478bd9Sstevel@tonic-gate gss_name_t *output_name; 567c478bd9Sstevel@tonic-gate { 577c478bd9Sstevel@tonic-gate krb5_context context; 587c478bd9Sstevel@tonic-gate krb5_principal princ; 597c478bd9Sstevel@tonic-gate krb5_error_code code; 607c478bd9Sstevel@tonic-gate char *stringrep, *tmp, *tmp2, *cp; 617c478bd9Sstevel@tonic-gate OM_uint32 length; 627c478bd9Sstevel@tonic-gate #ifndef NO_PASSWORD 637c478bd9Sstevel@tonic-gate struct passwd *pw; 647c478bd9Sstevel@tonic-gate #endif 657c478bd9Sstevel@tonic-gate 66*ab9b2e15Sgtb code = krb5_gss_init_context(&context); 67*ab9b2e15Sgtb if (code) { 68*ab9b2e15Sgtb *minor_status = code; 69*ab9b2e15Sgtb return GSS_S_FAILURE; 70*ab9b2e15Sgtb } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* set up default returns */ 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate *output_name = NULL; 757c478bd9Sstevel@tonic-gate *minor_status = 0; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* Go find the appropriate string rep to pass into parse_name */ 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate if ((input_name_type != GSS_C_NULL_OID) && 80*ab9b2e15Sgtb (g_OID_equal(input_name_type, gss_nt_service_name) || 817c478bd9Sstevel@tonic-gate g_OID_equal(input_name_type, gss_nt_service_name_v2))) { 827c478bd9Sstevel@tonic-gate char *service, *host; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate if ((tmp = 857c478bd9Sstevel@tonic-gate (char *) xmalloc(input_name_buffer->length + 1)) == NULL) { 867c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 87*ab9b2e15Sgtb krb5_free_context(context); 887c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate memcpy(tmp, input_name_buffer->value, input_name_buffer->length); 927c478bd9Sstevel@tonic-gate tmp[input_name_buffer->length] = 0; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate service = tmp; 95*ab9b2e15Sgtb if ((host = strchr(tmp, '@'))) { 967c478bd9Sstevel@tonic-gate *host = '\0'; 977c478bd9Sstevel@tonic-gate host++; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate code = krb5_sname_to_principal(context, host, service, KRB5_NT_SRV_HST, 1017c478bd9Sstevel@tonic-gate &princ); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate xfree(tmp); 1047c478bd9Sstevel@tonic-gate } else if ((input_name_type != GSS_C_NULL_OID) && 1057c478bd9Sstevel@tonic-gate (g_OID_equal(input_name_type, gss_nt_krb5_principal))) { 1067c478bd9Sstevel@tonic-gate krb5_principal input; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate if (input_name_buffer->length != sizeof(krb5_principal)) { 1097c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_WRONG_SIZE; 110*ab9b2e15Sgtb krb5_free_context(context); 1117c478bd9Sstevel@tonic-gate return(GSS_S_BAD_NAME); 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate input = *((krb5_principal *) input_name_buffer->value); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if ((code = krb5_copy_principal(context, input, &princ))) { 1177c478bd9Sstevel@tonic-gate *minor_status = code; 118*ab9b2e15Sgtb krb5_free_context(context); 1197c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate } else { 122*ab9b2e15Sgtb #ifndef NO_PASSWORD 123*ab9b2e15Sgtb uid_t uid; 124*ab9b2e15Sgtb struct passwd pwx; 125*ab9b2e15Sgtb char pwbuf[BUFSIZ]; 126*ab9b2e15Sgtb #endif 127*ab9b2e15Sgtb 1287c478bd9Sstevel@tonic-gate stringrep = NULL; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate if ((tmp = 1317c478bd9Sstevel@tonic-gate (char *) xmalloc(input_name_buffer->length + 1)) == NULL) { 1327c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 133*ab9b2e15Sgtb krb5_free_context(context); 1347c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate tmp2 = 0; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate memcpy(tmp, input_name_buffer->value, input_name_buffer->length); 1397c478bd9Sstevel@tonic-gate tmp[input_name_buffer->length] = 0; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate if ((input_name_type == GSS_C_NULL_OID) || 1427c478bd9Sstevel@tonic-gate g_OID_equal(input_name_type, gss_nt_krb5_name) || 143*ab9b2e15Sgtb g_OID_equal(input_name_type, gss_nt_user_name)) { 1447c478bd9Sstevel@tonic-gate stringrep = (char *) tmp; 1457c478bd9Sstevel@tonic-gate #ifndef NO_PASSWORD 146*ab9b2e15Sgtb } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) { 147*ab9b2e15Sgtb uid = *(uid_t *) input_name_buffer->value; 148*ab9b2e15Sgtb do_getpwuid: 149*ab9b2e15Sgtb if (k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) == 0) 150*ab9b2e15Sgtb stringrep = pw->pw_name; 1517c478bd9Sstevel@tonic-gate else 1527c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_NOUSER; 153*ab9b2e15Sgtb } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) { 154*ab9b2e15Sgtb uid = atoi(tmp); 155*ab9b2e15Sgtb goto do_getpwuid; 1567c478bd9Sstevel@tonic-gate #endif 1577c478bd9Sstevel@tonic-gate } else if (g_OID_equal(input_name_type, gss_nt_exported_name)) { 1587c478bd9Sstevel@tonic-gate cp = tmp; 1597c478bd9Sstevel@tonic-gate if (*cp++ != 0x04) 1607c478bd9Sstevel@tonic-gate goto fail_name; 1617c478bd9Sstevel@tonic-gate if (*cp++ != 0x01) 1627c478bd9Sstevel@tonic-gate goto fail_name; 1637c478bd9Sstevel@tonic-gate if (*cp++ != 0x00) 1647c478bd9Sstevel@tonic-gate goto fail_name; 1657c478bd9Sstevel@tonic-gate length = *cp++; 1667c478bd9Sstevel@tonic-gate if (length != gss_mech_krb5->length+2) 1677c478bd9Sstevel@tonic-gate goto fail_name; 1687c478bd9Sstevel@tonic-gate if (*cp++ != 0x06) 1697c478bd9Sstevel@tonic-gate goto fail_name; 1707c478bd9Sstevel@tonic-gate length = *cp++; 1717c478bd9Sstevel@tonic-gate if (length != gss_mech_krb5->length) 1727c478bd9Sstevel@tonic-gate goto fail_name; 1737c478bd9Sstevel@tonic-gate if (memcmp(cp, gss_mech_krb5->elements, length) != 0) 1747c478bd9Sstevel@tonic-gate goto fail_name; 1757c478bd9Sstevel@tonic-gate cp += length; 1767c478bd9Sstevel@tonic-gate length = *cp++; 1777c478bd9Sstevel@tonic-gate length = (length << 8) | *cp++; 1787c478bd9Sstevel@tonic-gate length = (length << 8) | *cp++; 1797c478bd9Sstevel@tonic-gate length = (length << 8) | *cp++; 1807c478bd9Sstevel@tonic-gate tmp2 = malloc(length+1); 1817c478bd9Sstevel@tonic-gate if (tmp2 == NULL) { 1827c478bd9Sstevel@tonic-gate xfree(tmp); 1837c478bd9Sstevel@tonic-gate *minor_status = ENOMEM; 184*ab9b2e15Sgtb krb5_free_context(context); 1857c478bd9Sstevel@tonic-gate return GSS_S_FAILURE; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate strncpy(tmp2, cp, length); 1887c478bd9Sstevel@tonic-gate tmp2[length] = 0; 189*ab9b2e15Sgtb 1907c478bd9Sstevel@tonic-gate stringrep = tmp2; 1917c478bd9Sstevel@tonic-gate } else { 192*ab9b2e15Sgtb xfree(tmp); 193*ab9b2e15Sgtb krb5_free_context(context); 1947c478bd9Sstevel@tonic-gate return(GSS_S_BAD_NAMETYPE); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* at this point, stringrep is set, or if not, *minor_status is. */ 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (stringrep) 2007c478bd9Sstevel@tonic-gate code = krb5_parse_name(context, (char *) stringrep, &princ); 2017c478bd9Sstevel@tonic-gate else { 2027c478bd9Sstevel@tonic-gate fail_name: 2037c478bd9Sstevel@tonic-gate xfree(tmp); 2047c478bd9Sstevel@tonic-gate if (tmp2) 2057c478bd9Sstevel@tonic-gate xfree(tmp2); 206*ab9b2e15Sgtb krb5_free_context(context); 2077c478bd9Sstevel@tonic-gate return(GSS_S_BAD_NAME); 2087c478bd9Sstevel@tonic-gate } 209*ab9b2e15Sgtb 2107c478bd9Sstevel@tonic-gate if (tmp2) 2117c478bd9Sstevel@tonic-gate xfree(tmp2); 2127c478bd9Sstevel@tonic-gate xfree(tmp); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* at this point, a krb5 function has been called to set princ. code 2167c478bd9Sstevel@tonic-gate contains the return status */ 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate if (code) { 2197c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) code; 220*ab9b2e15Sgtb krb5_free_context(context); 2217c478bd9Sstevel@tonic-gate return(GSS_S_BAD_NAME); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* save the name in the validation database */ 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate if (! kg_save_name((gss_name_t) princ)) { 2277c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ); 228*ab9b2e15Sgtb krb5_free_context(context); 2297c478bd9Sstevel@tonic-gate *minor_status = (OM_uint32) G_VALIDATE_FAILED; 2307c478bd9Sstevel@tonic-gate return(GSS_S_FAILURE); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 233*ab9b2e15Sgtb krb5_free_context(context); 234*ab9b2e15Sgtb 2357c478bd9Sstevel@tonic-gate /* return it */ 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate *output_name = (gss_name_t) princ; 2387c478bd9Sstevel@tonic-gate return(GSS_S_COMPLETE); 2397c478bd9Sstevel@tonic-gate } 240