[24319] | 1 | /* $Id: kerberos.c 3956 2010-01-05 20:56:56Z zacheiss $ |
---|
[23095] | 2 | * |
---|
| 3 | * Kerberos routines for registration server |
---|
| 4 | * |
---|
| 5 | * Copyright (C) 1998 by the Massachusetts Institute of Technology |
---|
| 6 | * For copying and distribution information, please see the file |
---|
| 7 | * <mit-copyright.h>. |
---|
| 8 | * |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | #include <mit-copyright.h> |
---|
| 12 | #include <moira.h> |
---|
| 13 | #include "reg_svr.h" |
---|
| 14 | |
---|
| 15 | #if !defined(KRB4) && !defined(KRB5) |
---|
| 16 | #define KRB5 |
---|
| 17 | #endif |
---|
| 18 | |
---|
| 19 | #include <errno.h> |
---|
| 20 | #include <string.h> |
---|
| 21 | |
---|
| 22 | #include <com_err.h> |
---|
| 23 | |
---|
| 24 | #define KRB5_DEPRECATED 1 |
---|
| 25 | #define KRB5_PRIVATE 1 |
---|
| 26 | |
---|
| 27 | #ifdef KRB4 |
---|
| 28 | #include <des.h> |
---|
| 29 | #include <kadm.h> |
---|
| 30 | #include <kadm_err.h> |
---|
| 31 | #include <krb.h> |
---|
| 32 | #endif |
---|
| 33 | |
---|
| 34 | #ifdef KRB5 |
---|
| 35 | #include <kadm5/admin.h> |
---|
| 36 | #include <krb5.h> |
---|
| 37 | |
---|
| 38 | krb5_context context; |
---|
| 39 | #endif |
---|
| 40 | |
---|
[24319] | 41 | RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/reg_svr/kerberos.c $ $Id: kerberos.c 3956 2010-01-05 20:56:56Z zacheiss $"); |
---|
[23095] | 42 | |
---|
| 43 | extern char *hostname, *shorthostname; |
---|
| 44 | |
---|
| 45 | #ifdef KRB5 |
---|
| 46 | long init_kerberos(void) |
---|
| 47 | { |
---|
| 48 | krb5_error_code code; |
---|
| 49 | |
---|
| 50 | /* Initialize Kerberos stuff. */ |
---|
| 51 | code = krb5_init_context(&context); |
---|
| 52 | if (code) |
---|
| 53 | return code; |
---|
| 54 | krb_set_tkt_string("/tmp/tkt_ureg"); |
---|
| 55 | return 0; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | /* Check the kerberos database to see if a principal exists */ |
---|
| 59 | long check_kerberos(char *username) |
---|
| 60 | { |
---|
| 61 | krb5_error_code code; |
---|
| 62 | krb5_creds creds; |
---|
| 63 | krb5_data *realm; |
---|
| 64 | krb5_timestamp now; |
---|
| 65 | #ifdef KERBEROS_TEST_REALM |
---|
| 66 | char ubuf[256]; |
---|
| 67 | |
---|
| 68 | sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM); |
---|
| 69 | username = ubuf; |
---|
| 70 | #endif |
---|
| 71 | |
---|
| 72 | memset(&creds, 0, sizeof(creds)); |
---|
| 73 | code = krb5_parse_name(context, username, &creds.client); |
---|
| 74 | if (code) |
---|
| 75 | goto cleanup; |
---|
| 76 | |
---|
| 77 | realm = krb5_princ_realm(context, creds.client); |
---|
| 78 | code = krb5_build_principal_ext(context, &creds.server, |
---|
| 79 | realm->length, realm->data, |
---|
| 80 | KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, |
---|
| 81 | realm->length, realm->data, 0); |
---|
| 82 | if (code) |
---|
| 83 | goto cleanup; |
---|
| 84 | |
---|
| 85 | code = krb5_timeofday(context, &now); |
---|
| 86 | if (code) |
---|
| 87 | goto cleanup; |
---|
| 88 | |
---|
| 89 | creds.times.starttime = 0; |
---|
| 90 | creds.times.endtime = now + 60; |
---|
| 91 | |
---|
| 92 | code = krb5_get_in_tkt_with_password(context, |
---|
| 93 | 0 /* options */, |
---|
| 94 | NULL /* addrs */, |
---|
| 95 | NULL /* ktypes */, |
---|
| 96 | NULL /* pre_auth_types */, |
---|
| 97 | "x" /* password */, |
---|
| 98 | NULL /* ccache */, |
---|
| 99 | &creds, |
---|
| 100 | NULL /* ret_as_reply */); |
---|
| 101 | |
---|
| 102 | cleanup: |
---|
| 103 | krb5_free_principal(context, creds.client); |
---|
| 104 | krb5_free_principal(context, creds.server); |
---|
| 105 | |
---|
| 106 | if (code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN) |
---|
| 107 | return MR_SUCCESS; |
---|
| 108 | else |
---|
| 109 | return MR_IN_USE; |
---|
| 110 | } |
---|
| 111 | |
---|
| 112 | /* Create a new principal in Kerberos */ |
---|
| 113 | long register_kerberos(char *username, char *password) |
---|
| 114 | { |
---|
| 115 | void *kadm_server_handle = NULL; |
---|
| 116 | kadm5_ret_t status; |
---|
| 117 | kadm5_principal_ent_rec princ; |
---|
| 118 | kadm5_policy_ent_rec defpol; |
---|
| 119 | kadm5_config_params realm_params; |
---|
| 120 | char admin_princ[256]; |
---|
| 121 | long mask = 0; |
---|
| 122 | #ifdef KERBEROS_TEST_REALM |
---|
| 123 | char ubuf[256]; |
---|
| 124 | |
---|
| 125 | sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM); |
---|
| 126 | sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM); |
---|
| 127 | username = ubuf; |
---|
| 128 | realm_params.realm = KERBEROS_TEST_REALM; |
---|
| 129 | realm_params.mask = KADM5_CONFIG_REALM; |
---|
| 130 | #else |
---|
| 131 | strcpy(admin_princ, REG_SVR_PRINCIPAL); |
---|
| 132 | realm_params.mask = 0; |
---|
| 133 | #endif |
---|
| 134 | |
---|
| 135 | memset(&princ, 0, sizeof(princ)); |
---|
| 136 | |
---|
| 137 | status = krb5_parse_name(context, username, &(princ.principal)); |
---|
| 138 | if (status) |
---|
| 139 | return status; |
---|
| 140 | |
---|
| 141 | |
---|
| 142 | status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE, |
---|
| 143 | &realm_params, KADM5_STRUCT_VERSION, |
---|
[24250] | 144 | KADM5_API_VERSION_2, NULL, &kadm_server_handle); |
---|
[23095] | 145 | if (status) |
---|
| 146 | goto cleanup; |
---|
| 147 | |
---|
| 148 | /* Assign "default" policy if it exists. */ |
---|
| 149 | if (!kadm5_get_policy(kadm_server_handle, "default", &defpol)) |
---|
| 150 | { |
---|
| 151 | princ.policy = "default"; |
---|
| 152 | mask |= KADM5_POLICY; |
---|
| 153 | (void) kadm5_free_policy_ent(kadm_server_handle, &defpol); |
---|
| 154 | } |
---|
| 155 | |
---|
| 156 | mask |= KADM5_PRINCIPAL; |
---|
| 157 | status = kadm5_create_principal(kadm_server_handle, &princ, mask, password); |
---|
| 158 | |
---|
| 159 | cleanup: |
---|
| 160 | krb5_free_principal(context, princ.principal); |
---|
| 161 | if (kadm_server_handle) |
---|
| 162 | kadm5_destroy(kadm_server_handle); |
---|
| 163 | |
---|
| 164 | if (status == KADM5_DUP) |
---|
| 165 | return MR_IN_USE; |
---|
| 166 | else if (status == KADM5_PASS_Q_TOOSHORT || |
---|
| 167 | status == KADM5_PASS_Q_CLASS || |
---|
| 168 | status == KADM5_PASS_Q_DICT) |
---|
| 169 | return MR_QUALITY; |
---|
| 170 | else return status; |
---|
| 171 | } |
---|
| 172 | #endif |
---|
| 173 | |
---|
| 174 | #ifdef KRB4 |
---|
| 175 | char realm[REALM_SZ]; |
---|
| 176 | |
---|
| 177 | long init_kerberos(void) |
---|
| 178 | { |
---|
| 179 | return krb_get_lrealm(realm, 1); |
---|
| 180 | } |
---|
| 181 | |
---|
| 182 | long check_kerberos(char *username) |
---|
| 183 | { |
---|
| 184 | long status; |
---|
| 185 | |
---|
| 186 | status = krb_get_pw_in_tkt(username, "", realm, "krbtgt", realm, 1, ""); |
---|
| 187 | if (status == KDC_PR_UNKNOWN) |
---|
| 188 | return MR_SUCCESS; |
---|
| 189 | else |
---|
| 190 | return MR_IN_USE; |
---|
| 191 | } |
---|
| 192 | |
---|
| 193 | long register_kerberos(char *username, char *password) |
---|
| 194 | { |
---|
| 195 | long status; |
---|
| 196 | Kadm_vals new; |
---|
| 197 | des_cblock key; |
---|
| 198 | unsigned long *lkey = (unsigned long *)key; |
---|
| 199 | |
---|
| 200 | if ((status = krb_get_svc_in_tkt(MOIRA_SNAME, shorthostname, realm, |
---|
| 201 | PWSERV_NAME, KADM_SINST, 3, KEYFILE))) |
---|
| 202 | return status; |
---|
| 203 | |
---|
| 204 | if ((status = kadm_init_link(PWSERV_NAME, KADM_SINST, realm)) != |
---|
| 205 | KADM_SUCCESS) |
---|
| 206 | return status; |
---|
| 207 | |
---|
| 208 | memset(&new, 0, sizeof(new)); |
---|
| 209 | SET_FIELD(KADM_DESKEY, new.fields); |
---|
| 210 | SET_FIELD(KADM_NAME, new.fields); |
---|
| 211 | |
---|
| 212 | des_string_to_key(password, key); |
---|
| 213 | new.key_low = htonl(lkey[0]); |
---|
| 214 | new.key_high = htonl(lkey[1]); |
---|
| 215 | strcpy(new.name, username); |
---|
| 216 | |
---|
| 217 | status = kadm_add(&new); |
---|
| 218 | memset(&new, 0, sizeof(new)); |
---|
| 219 | dest_tkt(); |
---|
| 220 | |
---|
| 221 | if (status == KADM_INUSE) |
---|
| 222 | return MR_IN_USE; |
---|
| 223 | else |
---|
| 224 | return status; |
---|
| 225 | } |
---|
| 226 | #endif |
---|