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
25 * shishi_principal_default_guess:
27 * Guesses a principal using getpwuid(getuid)), or if it fails, the
30 * Return value: Returns guessed default principal for user as a string that
31 * has to be deallocated with free() by the caller.
34 shishi_principal_default_guess (void)
43 return xstrdup (pw
->pw_name
);
45 return xstrdup ("user");
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.)
57 shishi_principal_default (Shishi
* handle
)
59 if (!handle
->default_principal
)
62 p
= shishi_principal_default_guess ();
63 shishi_principal_default_set (handle
, p
);
67 return handle
->default_principal
;
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
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.
81 shishi_principal_default_set (Shishi
* handle
, const char *principal
)
83 if (handle
->default_principal
)
84 free (handle
->default_principal
);
86 handle
->default_principal
= xstrdup (principal
);
88 handle
->default_principal
= NULL
;
92 shishi_parse_name (Shishi
* handle
, const char *name
,
93 char **principal
, char **realm
)
100 return SHISHI_INVALID_PRINCIPAL_NAME
;
102 while (*p
&& (*p
!= '@' || escaped
))
105 else if (*p
++ == '\\')
110 *principal
= xstrndup (name
, p
- name
+ 1);
111 (*principal
)[p
- name
] = '\0';
121 else if (*q
++ == '\\')
125 return SHISHI_INVALID_PRINCIPAL_NAME
;
128 *realm
= xstrdup (p
);
131 *realm
= xstrdup (shishi_realm_default (handle
));
137 2.1.1. Kerberos Principal Name Form
139 This name form shall be represented by the Object Identifier {iso(1)
140 member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
141 krb5(2) krb5_name(1)}. The recommended symbolic name for this type
142 is "GSS_KRB5_NT_PRINCIPAL_NAME".
144 This name type corresponds to the single-string representation of a
145 Kerberos name. (Within the MIT Kerberos V5 implementation, such
146 names are parseable with the krb5_parse_name() function.) The
147 elements included within this name representation are as follows,
148 proceeding from the beginning of the string:
150 (1) One or more principal name components; if more than one
151 principal name component is included, the components are
152 separated by `/`. Arbitrary octets may be included within
153 principal name components, with the following constraints and
154 special considerations:
156 (1a) Any occurrence of the characters `@` or `/` within a
157 name component must be immediately preceded by the `\`
158 quoting character, to prevent interpretation as a component
161 (1b) The ASCII newline, tab, backspace, and null characters
162 may occur directly within the component or may be
163 represented, respectively, by `\n`, `\t`, `\b`, or `\0`.
165 (1c) If the `\` quoting character occurs outside the contexts
166 described in (1a) and (1b) above, the following character is
167 interpreted literally. As a special case, this allows the
168 doubled representation `\\` to represent a single occurrence
169 of the quoting character.
171 (1d) An occurrence of the `\` quoting character as the last
172 character of a component is illegal.
174 (2) Optionally, a `@` character, signifying that a realm name
175 immediately follows. If no realm name element is included, the
176 local realm name is assumed. The `/` , `:`, and null characters
177 may not occur within a realm name; the `@`, newline, tab, and
178 backspace characters may be included using the quoting
179 conventions described in (1a), (1b), and (1c) above.
183 shishi_principal_name_get (Shishi
* handle
,
184 Shishi_asn1 namenode
,
185 const char *namefield
, char *out
, size_t * outlen
)
193 /* FIXME: allocate output instead of writing inline */
195 asprintf (&format
, "%s.name-string", namefield
);
196 res
= shishi_asn1_number_of_elements (handle
, namenode
, format
, &n
);
198 if (res
!= SHISHI_OK
)
202 for (i
= 1; i
<= n
; i
++)
204 len
= *outlen
- totlen
;
205 asprintf (&format
, "%s.name-string.?%d", namefield
, i
);
206 res
= shishi_asn1_read (handle
, namenode
, format
, &out
[totlen
], &len
);
208 if (res
!= SHISHI_OK
)
211 for (j
= 0; j
< len
; j
++)
213 if (out
[totlen
] == '@' || out
[totlen
] == '/' || out
[totlen
] == '\\')
215 if (totlen
+ strlen ("\\") > *outlen
)
216 return SHISHI_TOO_SMALL_BUFFER
;
217 out
[totlen
+ 1] = out
[totlen
];
228 if (totlen
+ strlen ("/") > *outlen
)
229 return SHISHI_TOO_SMALL_BUFFER
;
241 shishi_principal_name_realm_get (Shishi
* handle
,
242 Shishi_asn1 namenode
,
243 const char *namefield
,
244 Shishi_asn1 realmnode
,
245 const char *realmfield
,
246 char *out
, size_t * outlen
)
252 /* FIXME: allocate output instead of writing inline */
255 res
= shishi_principal_name_get (handle
, namenode
, namefield
, out
, &totlen
);
256 if (res
!= SHISHI_OK
)
259 if (realmnode
== NULL
&& realmfield
)
261 if (totlen
+ strlen ("@") + strlen (realmfield
) > *outlen
)
262 return SHISHI_TOO_SMALL_BUFFER
;
264 memcpy (out
+ totlen
, "@", strlen ("@"));
265 totlen
+= strlen ("@");
266 memcpy (out
+ totlen
, realmfield
, strlen (realmfield
));
267 totlen
+= strlen (realmfield
);
269 else if (realmnode
!= NULL
)
271 if (totlen
+ strlen ("@") > *outlen
)
272 return SHISHI_TOO_SMALL_BUFFER
;
274 memcpy (out
+ totlen
, "@", strlen ("@"));
275 totlen
+= strlen ("@");
277 len
= *outlen
- totlen
;
278 res
= shishi_asn1_read (handle
, realmnode
, realmfield
,
280 if (res
== SHISHI_ASN1_NO_ELEMENT
)
282 else if (res
!= SHISHI_OK
)
294 * shishi_principal_name_set:
295 * @handle: shishi handle as allocated by shishi_init().
296 * @namenode: ASN.1 structure with principal in @namefield.
297 * @namefield: name of field in namenode containing principal name.
298 * @name_type: type of principial, see Shishi_name_type, usually
300 * @name: zero-terminated input array with principal name.
302 * Set the given principal name field to given name.
304 * Return value: Returns SHISHI_OK iff successful.
307 shishi_principal_name_set (Shishi
* handle
,
308 Shishi_asn1 namenode
,
309 const char *namefield
,
310 Shishi_name_type name_type
, const char *name
[])
316 asprintf (&asn1name
, "%s.name-type", namefield
);
317 res
= shishi_asn1_write_int32 (handle
, namenode
, asn1name
, name_type
);
319 if (res
!= SHISHI_OK
)
322 asprintf (&asn1name
, "%s.name-string", namefield
);
323 res
= shishi_asn1_write (handle
, namenode
, asn1name
, NULL
, 0);
325 if (res
!= SHISHI_OK
)
331 asprintf (&asn1name
, "%s.name-string", namefield
);
332 res
= shishi_asn1_write (handle
, namenode
, asn1name
, "NEW", 1);
334 if (res
!= SHISHI_OK
)
337 asprintf (&asn1name
, "%s.name-string.?%d", namefield
, i
);
338 res
= shishi_asn1_write (handle
, namenode
, asn1name
, name
[i
- 1], 0);
340 if (res
!= SHISHI_OK
)
350 * shishi_principal_set:
351 * @handle: shishi handle as allocated by shishi_init().
352 * @namenode: ASN.1 structure with principal in @namefield.
353 * @namefield: name of field in namenode containing principal name.
354 * @name: zero-terminated string with principal name on RFC 1964 form.
356 * Set principal name field in ASN.1 structure to given name.
358 * Return value: Returns SHISHI_OK iff successful.
361 shishi_principal_set (Shishi
* handle
,
362 Shishi_asn1 namenode
,
363 const char *namefield
, const char *name
)
366 const char **namebuf
;
371 tmpname
= xstrdup (name
);
372 namebuf
= xmalloc (sizeof (*namebuf
));
375 (namebuf
[i
] = strtok_r (i
== 0 ? tmpname
: NULL
, "/", &tokptr
)); i
++)
377 namebuf
= xrealloc (namebuf
, (i
+ 2) * sizeof (*namebuf
));
380 res
= shishi_principal_name_set (handle
, namenode
, namefield
,
381 SHISHI_NT_UNKNOWN
, namebuf
);
384 if (res
!= SHISHI_OK
)
386 shishi_error_printf (handle
, _("Could not set principal name: %s\n"),
387 shishi_strerror (res
));
395 shishi_server_for_local_service (Shishi
* handle
, const char *service
)
397 char buf
[HOST_NAME_MAX
];
400 strcpy (buf
, service
);
403 ret
= gethostname (&buf
[strlen (service
) + 1],
404 sizeof (buf
) - strlen (service
) - 1);
405 buf
[sizeof (buf
) - 1] = '\0';
408 strcpy (&buf
[strlen (service
) + 1], "localhost");
410 return xstrdup (buf
);