Windows global stuff:
[krb5.git] / src / lib / krb5 / os / an_to_ln.c
1 /*
2  * lib/krb5/os/an_to_ln.c
3  *
4  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  * 
23  *
24  * krb5_aname_to_localname()
25  */
26
27 #include "k5-int.h"
28
29 #ifndef min
30 #define min(a,b) ((a) > (b) ? (b) : (a))
31 #endif /* min */
32
33 int krb5_lname_username_fallback = 1;
34 extern char *krb5_lname_file;
35
36 #ifndef _MSDOS    
37
38 static krb5_error_code dbm_an_to_ln();
39 static krb5_error_code username_an_to_ln();
40
41 /*
42  Converts an authentication name to a local name suitable for use by
43  programs wishing a translation to an environment-specific name (e.g.
44  user account name).
45
46  lnsize specifies the maximum length name that is to be filled into
47  lname.
48  The translation will be null terminated in all non-error returns.
49
50  returns system errors, NOT_ENOUGH_SPACE
51 */
52
53 krb5_error_code
54 krb5_aname_to_localname(context, aname, lnsize, lname)
55     krb5_context context;
56         krb5_const_principal aname;
57         const int lnsize;
58         char *lname;
59 {
60         struct stat statbuf;
61
62         if (!stat(krb5_lname_file,&statbuf))
63                 return dbm_an_to_ln(context, aname, lnsize, lname);
64         if (krb5_lname_username_fallback)
65                 return username_an_to_ln(context, aname, lnsize, lname);
66         return KRB5_LNAME_CANTOPEN;
67 }
68
69 /*
70  * Implementation:  This version uses a DBM database, indexed by aname,
71  * to generate a lname.
72  *
73  * The entries in the database are normal C strings, and include the trailing
74  * null in the DBM datum.size.
75  */
76 static krb5_error_code
77 dbm_an_to_ln(context, aname, lnsize, lname)
78     krb5_context context;
79     krb5_const_principal aname;
80     const int lnsize;
81     char *lname;
82 {
83     DBM *db;
84     krb5_error_code retval;
85     datum key, contents;
86     char *princ_name;
87
88     if (retval = krb5_unparse_name(context, aname, &princ_name))
89         return(retval);
90     key.dptr = princ_name;
91     key.dsize = strlen(princ_name)+1;   /* need to store the NULL for
92                                            decoding */
93
94     db = dbm_open(krb5_lname_file, O_RDONLY, 0600);
95     if (!db) {
96         krb5_xfree(princ_name);
97         return KRB5_LNAME_CANTOPEN;
98     }
99
100     contents = dbm_fetch(db, key);
101
102     krb5_xfree(princ_name);
103
104     if (contents.dptr == NULL) {
105         retval = KRB5_LNAME_NOTRANS;
106     } else {
107         strncpy(lname, contents.dptr, lnsize);
108         if (lnsize < contents.dsize)
109             retval = KRB5_CONFIG_NOTENUFSPACE;
110         else if (lname[contents.dsize-1] != '\0')
111             retval = KRB5_LNAME_BADFORMAT;
112         else
113             retval = 0;
114     }
115     /* can't close until we copy the contents. */
116     (void) dbm_close(db);
117     return retval;
118 }
119 #endif /* _MSDOS */
120
121 /*
122  * Implementation:  This version checks the realm to see if it is the local
123  * realm; if so, and there is exactly one non-realm component to the name,
124  * that name is returned as the lname.
125  */
126 static krb5_error_code
127 username_an_to_ln(context, aname, lnsize, lname)
128     krb5_context context;
129     krb5_const_principal aname;
130     const int lnsize;
131     char *lname;
132 {
133     krb5_error_code retval;
134     char *def_realm;
135     int realm_length;
136
137     realm_length = krb5_princ_realm(context, aname)->length;
138     
139     if (retval = krb5_get_default_realm(context, &def_realm)) {
140         return(retval);
141     }
142     if (((size_t) realm_length != strlen(def_realm)) ||
143         (memcmp(def_realm, krb5_princ_realm(context, aname)->data, realm_length))) {
144         free(def_realm);
145         return KRB5_LNAME_NOTRANS;
146     }
147
148     if (krb5_princ_size(context, aname) != 1) {
149         if (krb5_princ_size(context, aname) == 2 ) {
150            /* Check to see if 2nd component is the local realm. */
151            if ( strncmp(krb5_princ_component(context, aname,1)->data,def_realm,
152                         realm_length) ||
153                 realm_length != krb5_princ_component(context, aname,1)->length)
154                 return KRB5_LNAME_NOTRANS;
155         }
156         else
157            /* no components or more than one component to non-realm part of name
158            --no translation. */
159             return KRB5_LNAME_NOTRANS;
160     }
161
162     free(def_realm);
163     strncpy(lname, krb5_princ_component(context, aname,0)->data, 
164             min(krb5_princ_component(context, aname,0)->length,lnsize));
165     if (lnsize < krb5_princ_component(context, aname,0)->length ) {
166         retval = KRB5_CONFIG_NOTENUFSPACE;
167     } else {
168         lname[krb5_princ_component(context, aname,0)->length] = '\0';
169         retval = 0;
170     }
171     return retval;
172 }
173
174 #ifdef _MSDOS
175
176 krb5_error_code
177 krb5_aname_to_localname(context, aname, lnsize, lname)
178     krb5_context context;
179         krb5_const_principal aname;
180         const int lnsize;
181         char *lname;
182 {
183         if (krb5_lname_username_fallback)
184                 return username_an_to_ln(context, aname, lnsize, lname);
185         return KRB5_LNAME_CANTOPEN;
186 }
187
188 #endif /* _MSDOS */