1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* kprop/kprop_util.c */
3 /*
4 * Copyright (C) 2010 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. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26
27 /* sockaddr2krbaddr() utility function used by kprop and kpropd */
28
29 #include "k5-int.h"
30 #include "kprop.h"
31
32 /* Construct a host-based principal, similar to krb5_sname_to_principal() but
33 * with a specified realm. */
34 krb5_error_code
sn2princ_realm(krb5_context context,const char * hostname,const char * sname,const char * realm,krb5_principal * princ_out)35 sn2princ_realm(krb5_context context, const char *hostname, const char *sname,
36 const char *realm, krb5_principal *princ_out)
37 {
38 krb5_error_code ret;
39 krb5_principal princ;
40
41 *princ_out = NULL;
42 assert(sname != NULL && realm != NULL);
43
44 ret = krb5_sname_to_principal(context, hostname, sname, KRB5_NT_SRV_HST,
45 &princ);
46 if (ret)
47 return ret;
48
49 ret = krb5_set_principal_realm(context, princ, realm);
50 if (ret) {
51 krb5_free_principal(context, princ);
52 return ret;
53 }
54
55 *princ_out = princ;
56 return 0;
57 }
58
59 void
encode_database_size(uint64_t size,krb5_data * buf)60 encode_database_size(uint64_t size, krb5_data *buf)
61 {
62 assert(buf->length >= 12);
63 if (size > 0 && size <= UINT32_MAX) {
64 /* Encode in 32 bits for backward compatibility. */
65 store_32_be(size, buf->data);
66 buf->length = 4;
67 } else {
68 /* Set the first 32 bits to 0 and encode in the following 64 bits. */
69 store_32_be(0, buf->data);
70 store_64_be(size, buf->data + 4);
71 buf->length = 12;
72 }
73 }
74
75 krb5_error_code
decode_database_size(const krb5_data * buf,uint64_t * size_out)76 decode_database_size(const krb5_data *buf, uint64_t *size_out)
77 {
78 uint64_t size;
79
80 if (buf->length == 12) {
81 /* A 12-byte buffer must have the first four bytes zeroed. */
82 if (load_32_be(buf->data) != 0)
83 return KRB5KRB_ERR_GENERIC;
84
85 /* The size is stored in the next 64 bits. Values from 1..2^32-1 must
86 * be encoded in four bytes. */
87 size = load_64_be(buf->data + 4);
88 if (size > 0 && size <= UINT32_MAX)
89 return KRB5KRB_ERR_GENERIC;
90 } else if (buf->length == 4) {
91 size = load_32_be(buf->data);
92 } else {
93 /* Invalid buffer size. */
94 return KRB5KRB_ERR_GENERIC;
95 }
96
97 *size_out = size;
98 return 0;
99 }
100