Disable dependencies (to speed things up).
[shishi.git] / lib / principal.c
bloba1c06e396b627c45518bd7ac15f9de8c067f4d6f
1 /* principal.c get and set default principal
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 /**
25 * shishi_principal_default_guess:
27 * Guesses a principal using getpwuid(getuid)), or if it fails, the
28 * string "user".
30 * Return value: Returns guessed default principal for user as a string that
31 * has to be deallocated with free() by the caller.
32 **/
33 char *
34 shishi_principal_default_guess (void)
36 uid_t uid;
37 struct passwd *pw;
39 uid = getuid ();
40 pw = getpwuid (uid);
42 if (pw)
43 return strdup (pw->pw_name);
44 else
45 return strdup ("user");
49 /**
50 * shishi_principal_default:
51 * @handle: Shishi library handle create by shishi_init().
53 * Return value: Returns the default principal name used in the
54 * library. (Not a copy of it, so don't modify or deallocate it.)
55 **/
56 const char *
57 shishi_principal_default (Shishi * handle)
59 if (!handle->default_principal)
61 char *p;
62 p = shishi_principal_default_guess ();
63 shishi_principal_default_set (handle, p);
64 free (p);
67 return handle->default_principal;
70 /**
71 * shishi_principal_default_set:
72 * @handle: Shishi library handle create by shishi_init().
73 * @principal: string with new default principal name, or NULL to
74 * reset to default.
76 * Set the default realm used in the library. The string is copied
77 * into the library, so you can dispose of the variable immediately
78 * after calling this function.
79 **/
80 void
81 shishi_principal_default_set (Shishi * handle, const char *principal)
83 if (handle->default_principal)
84 free (handle->default_principal);
85 if (principal)
86 handle->default_principal = strdup (principal);
87 else
88 handle->default_principal = NULL;
92 2.1.1. Kerberos Principal Name Form
94 This name form shall be represented by the Object Identifier {iso(1)
95 member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
96 krb5(2) krb5_name(1)}. The recommended symbolic name for this type
97 is "GSS_KRB5_NT_PRINCIPAL_NAME".
99 This name type corresponds to the single-string representation of a
100 Kerberos name. (Within the MIT Kerberos V5 implementation, such
101 names are parseable with the krb5_parse_name() function.) The
102 elements included within this name representation are as follows,
103 proceeding from the beginning of the string:
105 (1) One or more principal name components; if more than one
106 principal name component is included, the components are
107 separated by `/`. Arbitrary octets may be included within
108 principal name components, with the following constraints and
109 special considerations:
111 (1a) Any occurrence of the characters `@` or `/` within a
112 name component must be immediately preceded by the `\`
113 quoting character, to prevent interpretation as a component
114 or realm separator.
116 (1b) The ASCII newline, tab, backspace, and null characters
117 may occur directly within the component or may be
118 represented, respectively, by `\n`, `\t`, `\b`, or `\0`.
120 (1c) If the `\` quoting character occurs outside the contexts
121 described in (1a) and (1b) above, the following character is
122 interpreted literally. As a special case, this allows the
123 doubled representation `\\` to represent a single occurrence
124 of the quoting character.
126 (1d) An occurrence of the `\` quoting character as the last
127 character of a component is illegal.
129 (2) Optionally, a `@` character, signifying that a realm name
130 immediately follows. If no realm name element is included, the
131 local realm name is assumed. The `/` , `:`, and null characters
132 may not occur within a realm name; the `@`, newline, tab, and
133 backspace characters may be included using the quoting
134 conventions described in (1a), (1b), and (1c) above.
138 shishi_principal_name_get (Shishi * handle,
139 Shishi_asn1 namenode,
140 const char *namefield, char *out, size_t * outlen)
142 int res;
143 char format[BUFSIZ];
144 size_t totlen = 0;
145 int len;
146 int i, j, n;
148 sprintf (format, "%s.name-string", namefield);
149 res = shishi_asn1_number_of_elements (handle, namenode, format, &n);
150 if (res != SHISHI_OK)
151 return res;
153 totlen = 0;
154 for (i = 1; i <= n; i++)
156 len = *outlen - totlen;
157 sprintf (format, "%s.name-string.?%d", namefield, i);
158 res = shishi_asn1_read (handle, namenode, format, &out[totlen], &len);
159 if (res != SHISHI_OK)
160 return res;
162 for (j = 0; j < len; j++)
164 if (out[totlen] == '@' || out[totlen] == '/' || out[totlen] == '\\')
166 if (totlen + strlen ("\\") > *outlen)
167 return SHISHI_TOO_SMALL_BUFFER;
168 out[totlen + 1] = out[totlen];
169 out[totlen] = '\\';
170 len++;
171 totlen++;
172 j++;
174 totlen++;
177 if (i < n)
179 if (totlen + strlen ("/") > *outlen)
180 return SHISHI_TOO_SMALL_BUFFER;
181 out[totlen] = '/';
182 totlen++;
186 *outlen = totlen;
188 return SHISHI_OK;
192 shishi_principal_name_realm_get (Shishi * handle,
193 Shishi_asn1 namenode,
194 const char *namefield,
195 Shishi_asn1 realmnode,
196 const char *realmfield,
197 char *out, size_t * outlen)
199 int res;
200 size_t totlen = 0;
201 int len;
203 totlen = *outlen;
204 res = shishi_principal_name_get (handle, namenode, namefield, out, &totlen);
205 if (res != SHISHI_OK)
206 return res;
208 if (realmnode == NULL && realmfield)
210 if (totlen + strlen ("@") + strlen (realmfield) > *outlen)
211 return SHISHI_TOO_SMALL_BUFFER;
213 memcpy (out + totlen, "@", strlen ("@"));
214 totlen += strlen ("@");
215 memcpy (out + totlen, realmfield, strlen (realmfield));
216 totlen += strlen (realmfield);
218 else if (realmnode != NULL)
220 if (totlen + strlen ("@") > *outlen)
221 return SHISHI_TOO_SMALL_BUFFER;
223 memcpy (out + totlen, "@", strlen ("@"));
224 totlen += strlen ("@");
226 len = *outlen - totlen;
227 res = shishi_asn1_read (handle, realmnode, realmfield,
228 &out[totlen], &len);
229 if (res == SHISHI_ASN1_NO_ELEMENT)
230 totlen--;
231 else if (res != SHISHI_OK)
232 return res;
233 else
234 totlen += len;
237 *outlen = totlen;
239 return SHISHI_OK;
243 * shishi_principal_name_set:
244 * @handle: shishi handle as allocated by shishi_init().
245 * @namenode: ASN.1 structure with principal in @namefield.
246 * @namefield: name of field in namenode containing principal name.
247 * @name_type: type of principial, see Shishi_name_type, usually
248 * SHISHI_NT_UNKNOWN.
249 * @sname: zero-terminated input array with principal name.
251 * Set the given principal name field to given name.
253 * Return value: Returns SHISHI_OK iff successful.
256 shishi_principal_name_set (Shishi * handle,
257 Shishi_asn1 namenode,
258 const char *namefield,
259 Shishi_name_type name_type, const char *name[])
261 int res;
262 char *buf, *asn1name;
263 int i;
265 asprintf (&buf, "%d", name_type);
266 asprintf (&asn1name, "%s.name-type", namefield);
267 res = shishi_asn1_write (handle, namenode, asn1name, buf, 0);
268 free (asn1name);
269 free (buf);
270 if (res != SHISHI_OK)
271 return res;
273 asprintf (&asn1name, "%s.name-string", namefield);
274 res = shishi_asn1_write (handle, namenode, asn1name, NULL, 0);
275 free (asn1name);
276 if (res != SHISHI_OK)
277 return res;
279 i = 1;
280 while (name[i - 1])
282 asprintf (&asn1name, "%s.name-string", namefield);
283 res = shishi_asn1_write (handle, namenode, asn1name, "NEW", 1);
284 free (asn1name);
285 if (res != SHISHI_OK)
286 return res;
288 asprintf (&asn1name, "%s.name-string.?%d", namefield, i);
289 res = shishi_asn1_write (handle, namenode, asn1name, name[i - 1], 0);
290 free (asn1name);
291 if (res != SHISHI_OK)
292 return res;
294 i++;
297 return SHISHI_OK;
301 * shishi_principal_set:
302 * @namenode: ASN.1 structure with principal in @namefield.
303 * @namefield: name of field in namenode containing principal name.
304 * @name: zero-terminated string with principal name on RFC 1964 form.
306 * Set principal name field in ASN.1 structure to given name.
308 * Return value: Returns SHISHI_OK iff successful.
311 shishi_principal_set (Shishi * handle,
312 Shishi_asn1 namenode,
313 const char *namefield, const char *name)
315 char *tmpname;
316 const char **namebuf;
317 char *tokptr;
318 int res;
319 int i;
321 tmpname = strdup (name);
322 if (tmpname == NULL)
323 return SHISHI_MALLOC_ERROR;
325 namebuf = malloc (sizeof (*namebuf));
326 if (namebuf == NULL)
327 return SHISHI_MALLOC_ERROR;
329 for (i = 0;
330 (namebuf[i] = strtok_r (i == 0 ? tmpname : NULL, "/", &tokptr)); i++)
332 namebuf = realloc (namebuf, (i + 2) * sizeof (*namebuf));
333 if (namebuf == NULL)
334 return SHISHI_MALLOC_ERROR;
337 res = shishi_principal_name_set (handle, namenode, namefield,
338 SHISHI_NT_UNKNOWN, namebuf);
339 if (res != SHISHI_OK)
341 shishi_error_printf (handle, _("Could not set principal name: %s\n"),
342 shishi_strerror (res));
343 return res;
346 free (namebuf);
347 free (tmpname);
349 return SHISHI_OK;