]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Header$ | |
5 | * | |
6 | * Copyright (C) 1987 by the Massachusetts Institute of Technology | |
7 | * For copying and distribution information, please see the file | |
8 | * <mit-copyright.h>. | |
9 | * | |
10 | * Glue routines to allow the database stuff to be linked in to | |
11 | * a program expecting a library level interface. | |
12 | */ | |
13 | ||
14 | #ifndef lint | |
15 | static char *rcsid_mr_glue_c = "$Header$"; | |
16 | #endif lint | |
17 | ||
18 | #include <mit-copyright.h> | |
19 | #include <sys/types.h> | |
20 | #include <sys/signal.h> | |
21 | #include <sys/wait.h> | |
22 | #include <krb_et.h> | |
23 | #include <pwd.h> | |
24 | #include "mr_server.h" | |
25 | #include "query.h" | |
26 | ||
27 | static int already_connected = 0; | |
28 | ||
29 | #define CHECK_CONNECTED { if (!already_connected) return MR_NOT_CONNECTED; } | |
30 | ||
31 | static client pseudo_client; | |
32 | extern int errno; | |
33 | extern char *whoami; | |
34 | extern time_t now; | |
35 | void reapchild(); | |
36 | ||
37 | mr_connect(server) | |
38 | char *server; | |
39 | { | |
40 | register int status; | |
41 | extern int query_timeout; | |
42 | struct sigaction action; | |
43 | ||
44 | if (already_connected) return MR_ALREADY_CONNECTED; | |
45 | ||
46 | initialize_sms_error_table(); | |
47 | initialize_krb_error_table(); | |
48 | memset((char *)&pseudo_client, 0, sizeof(pseudo_client)); /* XXX */ | |
49 | ||
50 | query_timeout = 0; | |
51 | status = mr_open_database(); | |
52 | if (!status) already_connected = 1; | |
53 | ||
54 | action.sa_flags = 0; | |
55 | sigemptyset(&action.sa_mask); | |
56 | sigaddset(&action.sa_mask, SIGCHLD); | |
57 | action.sa_handler = reapchild; | |
58 | if (sigaction(SIGCHLD, &action, NULL) < 0) { | |
59 | com_err(whoami, errno, "Unable to establish signal handlers."); | |
60 | exit(1); | |
61 | } | |
62 | return status; | |
63 | } | |
64 | ||
65 | mr_disconnect() | |
66 | { | |
67 | CHECK_CONNECTED; | |
68 | mr_close_database(); | |
69 | already_connected = 0; | |
70 | return 0; | |
71 | } | |
72 | ||
73 | mr_noop() | |
74 | { | |
75 | CHECK_CONNECTED; | |
76 | return 0; | |
77 | } | |
78 | /* | |
79 | * This routine is rather bogus, as it only fills in who you claim to be. | |
80 | */ | |
81 | mr_auth(prog) | |
82 | char *prog; | |
83 | { | |
84 | struct passwd *pw; | |
85 | extern char *krb_realm; | |
86 | char buf[1024], *strsave(); | |
87 | ||
88 | CHECK_CONNECTED; | |
89 | pw = getpwuid(getuid()); | |
90 | if (!pw) return (KDC_PR_UNKNOWN + ERROR_TABLE_BASE_krb); /* XXX hack (we | |
91 | * need an extended | |
92 | * error code table) | |
93 | */ | |
94 | strcpy(pseudo_client.kname.name, pw->pw_name); | |
95 | krb_get_lrealm(pseudo_client.kname.realm, 1); | |
96 | krb_realm = pseudo_client.kname.realm; | |
97 | ||
98 | strcpy(buf, pw->pw_name); | |
99 | strcat(buf, "@"); | |
100 | strcat(buf, pseudo_client.kname.realm); | |
101 | strcpy(pseudo_client.clname, buf); | |
102 | pseudo_client.users_id = 0; | |
103 | name_to_id(pseudo_client.kname.name, USERS_TABLE, &pseudo_client.users_id); | |
104 | pseudo_client.client_id = pseudo_client.users_id; | |
105 | strncpy(pseudo_client.entity, prog, 8); | |
106 | pseudo_client.args = (mr_params *) malloc(sizeof(mr_params)); | |
107 | pseudo_client.args->mr_version_no = MR_VERSION_2; | |
108 | return 0; | |
109 | } | |
110 | ||
111 | struct hint { | |
112 | int (*proc)(); | |
113 | char *hint; | |
114 | }; | |
115 | ||
116 | callback(argc, argv, arg) | |
117 | int argc; | |
118 | char **argv; | |
119 | struct hint *arg; | |
120 | { | |
121 | if (mr_trim_args(argc, argv) == MR_NO_MEM) { | |
122 | com_err(whoami, MR_NO_MEM, "while trimmming args"); | |
123 | } | |
124 | (*arg->proc)(argc, argv, arg->hint); | |
125 | } | |
126 | ||
127 | ||
128 | int mr_query(name, argc, argv, callproc, callarg) | |
129 | char *name; /* Query name */ | |
130 | int argc; /* Arg count */ | |
131 | char **argv; /* Args */ | |
132 | int (*callproc)(); /* Callback procedure */ | |
133 | char *callarg; /* Callback argument */ | |
134 | { | |
135 | struct hint hints; | |
136 | ||
137 | time(&now); | |
138 | hints.proc = callproc; | |
139 | hints.hint = callarg; | |
140 | next_incremental(); | |
141 | return mr_process_query(&pseudo_client, name, argc, | |
142 | mr_copy_args(argv, argc), callback, | |
143 | (char *)&hints); | |
144 | ||
145 | } | |
146 | ||
147 | int mr_access(name, argc, argv) | |
148 | char *name; /* Query name */ | |
149 | int argc; /* Arg count */ | |
150 | char **argv; /* Args */ | |
151 | { | |
152 | time(&now); | |
153 | return mr_check_access(&pseudo_client, name, argc, | |
154 | mr_copy_args(argv, argc)); | |
155 | } | |
156 | ||
157 | int mr_query_internal(argc, argv, callproc, callarg) | |
158 | int argc; | |
159 | char **argv; | |
160 | int (*callproc)(); | |
161 | char *callarg; | |
162 | { | |
163 | struct hint hints; | |
164 | ||
165 | time(&now); | |
166 | hints.proc = callproc; | |
167 | hints.hint = callarg; | |
168 | next_incremental(); | |
169 | return mr_process_query(&pseudo_client, argv[0], argc-1, | |
170 | mr_copy_args(argv+1, argc-1), callback, | |
171 | (char *)&hints); | |
172 | } | |
173 | ||
174 | int mr_access_internal(argc, argv) | |
175 | int argc; | |
176 | char **argv; | |
177 | { | |
178 | time(&now); | |
179 | return mr_check_access(&pseudo_client, argv[0], argc-1, | |
180 | mr_copy_args(argv+1, argc-1)); | |
181 | } | |
182 | ||
183 | mr_shutdown(why) | |
184 | char *why; | |
185 | { | |
186 | fprintf(stderr, "Sorry, not implemented\n"); | |
187 | } | |
188 | ||
189 | ||
190 | /* trigger_dcm is also used as a followup routine to the | |
191 | * set_server_host_override query, hence the two dummy arguments. | |
192 | */ | |
193 | ||
194 | struct query pseudo_query = { | |
195 | "trigger_dcm", | |
196 | "tdcm", | |
197 | }; | |
198 | ||
199 | trigger_dcm(dummy0, dummy1, cl) | |
200 | int dummy0, dummy1; | |
201 | client *cl; | |
202 | { | |
203 | register int pid, status; | |
204 | char prog[128]; | |
205 | ||
206 | if (status = check_query_access(&pseudo_query, 0, cl)) | |
207 | return(status); | |
208 | ||
209 | sprintf(prog, "%s/startdcm", BIN_DIR); | |
210 | pid = vfork(); | |
211 | switch (pid) { | |
212 | case 0: | |
213 | execl(prog, "startdcm", 0); | |
214 | exit(1); | |
215 | ||
216 | case -1: | |
217 | return(errno); | |
218 | ||
219 | default: | |
220 | return(MR_SUCCESS); | |
221 | } | |
222 | } | |
223 | ||
224 | ||
225 | void reapchild() | |
226 | { | |
227 | int status, pid; | |
228 | ||
229 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { | |
230 | if (pid == inc_pid) { | |
231 | inc_running = 0; | |
232 | next_incremental(); | |
233 | } | |
234 | if (WTERMSIG(status) != 0 || WEXITSTATUS(status) != 0) | |
235 | com_err(whoami, 0, "%d: child exits with signal %d status %d", | |
236 | pid, WTERMSIG(status), WEXITSTATUS(status)); | |
237 | } | |
238 | } |