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