]>
Commit | Line | Data |
---|---|---|
a3cf6921 | 1 | /* |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Header$ | |
5 | * | |
6 | * Copyright (C) 1987 by the Massachusetts Institute of Technology | |
c801de4c | 7 | * For copying and distribution information, please see the file |
8 | * <mit-copyright.h>. | |
a3cf6921 | 9 | * |
a3cf6921 | 10 | */ |
11 | ||
12 | #ifndef lint | |
59ec8dae | 13 | static char *rcsid_mr_sauth_c = "$Header$"; |
a3cf6921 | 14 | #endif lint |
15 | ||
c801de4c | 16 | #include <mit-copyright.h> |
03c05291 | 17 | #include <string.h> |
d548a4e7 | 18 | #include "mr_server.h" |
713cf9c9 | 19 | #include <ctype.h> |
40165bd0 | 20 | #include <krb_et.h> |
03c05291 | 21 | #include <moira.h> |
3d0d0f07 | 22 | #include <time.h> |
a3cf6921 | 23 | |
3d0d0f07 | 24 | extern char *whoami, *host; |
a3cf6921 | 25 | |
03c05291 | 26 | /* from libmoira */ |
27 | char *kname_unparse(char *, char *, char *); | |
c1665e6d | 28 | |
3d0d0f07 | 29 | typedef struct _replay_cache { |
30 | KTEXT_ST auth; | |
31 | time_t expires; | |
32 | struct _replay_cache *next; | |
33 | } replay_cache; | |
34 | ||
35 | replay_cache *rcache = NULL; | |
36 | ||
a3cf6921 | 37 | /* |
d548a4e7 | 38 | * Handle a MOIRA_AUTH RPC request. |
a3cf6921 | 39 | * |
40 | * argv[0] is a kerberos authenticator. Decompose it, and if | |
5eaef520 | 41 | * successful, store the name the user authenticated to in |
a3cf6921 | 42 | * cl->cl_name. |
43 | */ | |
44 | ||
5eaef520 | 45 | void do_auth(client *cl) |
a3cf6921 | 46 | { |
5eaef520 | 47 | KTEXT_ST auth; |
48 | AUTH_DAT ad; | |
49 | int status, ok; | |
50 | extern int errno; | |
51 | replay_cache *rc, *rcnew; | |
52 | time_t now; | |
53 | ||
54 | auth.length = cl->args->mr_argl[0]; | |
55 | memcpy(auth.dat, cl->args->mr_argv[0], auth.length); | |
56 | auth.mbz = 0; | |
57 | ||
58 | if ((status = krb_rd_req (&auth, MOIRA_SNAME, host, | |
59 | cl->haddr.sin_addr.s_addr, &ad, ""))) | |
60 | { | |
61 | status += ERROR_TABLE_BASE_krb; | |
62 | cl->reply.mr_status = status; | |
63 | if (log_flags & LOG_RES) | |
64 | com_err(whoami, status, " (authentication failed)"); | |
65 | return; | |
66 | } | |
67 | ||
68 | if (!rcache) | |
69 | { | |
70 | rcache = malloc(sizeof(replay_cache)); | |
71 | memset(rcache, 0, sizeof(replay_cache)); | |
72 | } | |
73 | ||
74 | /* scan replay cache */ | |
75 | for (rc = rcache->next; rc; rc = rc->next) | |
76 | { | |
77 | if (auth.length == rc->auth.length && | |
78 | !memcmp(&(auth.dat), &(rc->auth.dat), auth.length)) | |
79 | { | |
80 | com_err(whoami, 0, | |
81 | "Authenticator replay from %s using authenticator for %s", | |
82 | inet_ntoa(cl->haddr.sin_addr), | |
83 | kname_unparse(ad.pname, ad.pinst, ad.prealm)); | |
84 | com_err(whoami, KE_RD_AP_REPEAT, " (authentication failed)"); | |
85 | cl->reply.mr_status = KE_RD_AP_REPEAT; | |
86 | return; | |
3d0d0f07 | 87 | } |
5eaef520 | 88 | } |
89 | ||
90 | /* add new entry */ | |
91 | time(&now); | |
92 | rcnew = malloc(sizeof(replay_cache)); | |
93 | memcpy(&(rcnew->auth), &auth, sizeof(KTEXT_ST)); | |
94 | rcnew->expires = now + 2 * CLOCK_SKEW; | |
95 | rcnew->next = rcache->next; | |
96 | rcache->next = rcnew; | |
97 | ||
98 | /* clean cache */ | |
99 | for (rc = rcnew; rc->next; ) | |
100 | { | |
101 | if (rc->next->expires < now) | |
102 | { | |
103 | rcnew = rc->next; | |
104 | rc->next = rc->next->next; | |
105 | free(rcnew); | |
060e9c63 | 106 | } |
5eaef520 | 107 | else |
108 | rc = rc->next; | |
109 | } | |
110 | ||
111 | memcpy(cl->kname.name, ad.pname, ANAME_SZ); | |
112 | memcpy(cl->kname.inst, ad.pinst, INST_SZ); | |
113 | memcpy(cl->kname.realm, ad.prealm, REALM_SZ); | |
114 | strcpy(cl->clname, kname_unparse(ad.pname, ad.pinst, ad.prealm)); | |
115 | ||
116 | if (ad.pinst[0] == 0 && !strcmp(ad.prealm, krb_realm)) | |
117 | ok = 1; | |
118 | else | |
119 | ok = 0; | |
120 | /* this is in a separate function because it accesses the database */ | |
121 | status = set_krb_mapping(cl->clname, ad.pname, ok, | |
122 | &cl->client_id, &cl->users_id); | |
123 | ||
124 | if (cl->args->mr_version_no == MR_VERSION_2) | |
125 | { | |
126 | strncpy(cl->entity, cl->args->mr_argv[1], 8); | |
127 | cl->entity[8] = 0; | |
128 | } | |
129 | else | |
130 | strcpy(cl->entity, "???"); | |
131 | memset(&ad, 0, sizeof(ad)); /* Clean up session key, etc. */ | |
132 | ||
133 | if (log_flags & LOG_RES) | |
134 | { | |
135 | com_err(whoami, 0, "Auth to %s using %s, uid %d cid %d", | |
136 | cl->clname, cl->entity, cl->users_id, cl->client_id); | |
137 | } | |
138 | if (status != MR_SUCCESS) | |
139 | cl->reply.mr_status = status; | |
140 | else if (cl->users_id == 0) | |
141 | cl->reply.mr_status = MR_USER_AUTH; | |
a3cf6921 | 142 | } |