Windows global stuff:
[krb5.git] / src / lib / gssapi / krb5 / import_name.c
1 /*
2  * Copyright 1993 by OpenVision Technologies, Inc.
3  * 
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without fee,
6  * provided that the above copyright notice appears in all copies and
7  * that both that copyright notice and this permission notice appear in
8  * supporting documentation, and that the name of OpenVision not be used
9  * in advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission. OpenVision makes no
11  * representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  * 
14  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "gssapiP_krb5.h"
24 #ifndef NO_PASSWORD
25 #include <pwd.h>
26 #endif
27
28 #ifdef USE_STRING_H
29 #include <string.h>
30 #else
31 #include <strings.h>
32 #endif
33
34 /*
35  * errors:
36  * GSS_S_BAD_NAMETYPE   if the type is bogus
37  * GSS_S_BAD_NAME       if the type is good but the name is bogus
38  * GSS_S_FAILURE        if memory allocation fails
39  */
40
41 OM_uint32
42 krb5_gss_import_name(context, minor_status, input_name_buffer, 
43                      input_name_type, output_name)
44      krb5_context context;
45      OM_uint32 *minor_status;
46      gss_buffer_t input_name_buffer;
47      const_gss_OID input_name_type;
48      gss_name_t *output_name;
49 {
50    krb5_principal princ;
51    krb5_error_code code;
52    char *stringrep;
53 #ifndef NO_PASSWORD
54    struct passwd *pw;
55 #endif
56    /* set up default returns */
57
58    *output_name = NULL;
59    *minor_status = 0;
60
61    /* Go find the appropriate string rep to pass into parse_name */
62
63    if ((input_name_type != GSS_C_NULL_OID) &&
64        g_OID_equal(input_name_type, gss_nt_service_name)) {
65       char *tmp, *service, *host;
66
67       if ((tmp =
68            (char *) xmalloc(strlen(input_name_buffer->value)+1)) == NULL) {
69          *minor_status = ENOMEM;
70          return(GSS_S_FAILURE);
71       }
72
73       strcpy(tmp, input_name_buffer->value);
74
75       service = tmp;
76       if ((host = strchr(tmp, '@')) == NULL) {
77          xfree(tmp);
78          *minor_status = (OM_uint32) G_BAD_SERVICE_NAME;
79          return(GSS_S_BAD_NAME);
80       }
81       *host = '\0';
82       host++;
83
84       code = krb5_sname_to_principal(context, host, service, KRB5_NT_SRV_HST,
85                                      &princ);
86
87       xfree(tmp);
88    } else if ((input_name_type != GSS_C_NULL_OID) &&
89               (g_OID_equal(input_name_type, gss_nt_krb5_principal))) {
90       krb5_principal input;
91
92       if (input_name_buffer->length != sizeof(krb5_principal)) {
93          *minor_status = (OM_uint32) G_WRONG_SIZE;
94          return(GSS_S_BAD_NAME);
95       }
96
97       input = *((krb5_principal *) input_name_buffer->value);
98
99       if (code = krb5_copy_principal(context, input, &princ)) {
100          *minor_status = code;
101          return(GSS_S_FAILURE);
102       }
103    } else {
104       stringrep = NULL;
105
106       if ((input_name_type == GSS_C_NULL_OID) ||
107           g_OID_equal(input_name_type, gss_nt_krb5_name) ||
108           g_OID_equal(input_name_type, gss_nt_user_name)) {
109          stringrep = (char *) input_name_buffer->value;
110 #ifndef NO_PASSWORD
111       } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) {
112          if (pw = getpwuid(*((uid_t *) input_name_buffer->value)))
113             stringrep = pw->pw_name;
114          else
115             *minor_status = (OM_uint32) G_NOUSER;
116       } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) {
117          if (pw = getpwuid((uid_t) atoi(input_name_buffer->value)))
118             stringrep = pw->pw_name;
119          else
120             *minor_status = (OM_uint32) G_NOUSER;
121 #endif
122       } else {
123          return(GSS_S_BAD_NAMETYPE);
124       }
125
126       /* at this point, stringrep is set, or if not, *minor_status is. */
127
128       if (stringrep)
129          code = krb5_parse_name(context, (char *) stringrep, &princ);
130       else
131          return(GSS_S_BAD_NAME);
132    }
133
134    /* at this point, a krb5 function has been called to set princ.  code
135       contains the return status */
136
137    if (code) {
138       *minor_status = (OM_uint32) code;
139       return(GSS_S_BAD_NAME);
140    }
141
142    /* save the name in the validation database */
143
144    if (! kg_save_name((gss_name_t) princ)) {
145       krb5_free_principal(context, princ);
146       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
147       return(GSS_S_FAILURE);
148    }
149
150    /* return it */
151
152    *output_name = (gss_name_t) princ;
153    return(GSS_S_COMPLETE);
154 }