chiark / gitweb /
Add --spoof-user. Tidy up servicepw &c in daemon.
[userv.git] / ddebug.c
1 /*
2  * userv - ddebug.c
3  * routines which are different for -DDEBUG
4  *
5  * Copyright (C)1996-1997 Ian Jackson
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with userv; if not, write to the Free Software
19  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 #include <stdarg.h>
23 #include <syslog.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <grp.h>
29 #include <sys/types.h>
30
31 #include "config.h"
32 #include "common.h"
33 #include "daemon.h"
34 #include "lib.h"
35 #include "tokens.h"
36
37 #ifdef DEBUG
38
39 static const char *sl_ident= "UNSET";
40 static int sl_option=0, sl_facility=0;
41
42 void openlog(const char *ident, int option, int facility) {
43   sl_ident= ident;
44   sl_option= option;
45   sl_facility= facility;
46 }
47
48 void syslog(int priority, const char *fmt, ...) {
49   va_list al;
50   fprintf(stderr,"syslog: %s<%d.%d>(%d): ",sl_ident,sl_facility,priority,sl_option);
51   va_start(al,fmt);
52   vfprintf(stderr,fmt,al);
53   va_end(al);
54   fputc('\n',stderr);
55 }
56
57 void closelog(void) {
58   sl_ident= "CLOSED";
59   sl_option= sl_facility= 0;
60 }
61
62 static void fdwantdumprwhead(int *donehead, const char *whichstr, const char *rwstr) {
63   if (*donehead) return;
64   printf("fds %s%s%s:",whichstr,rwstr?" ":"",rwstr?rwstr:"");
65   *donehead= 1;
66 }
67
68 static void fdwantdumprw(const char *whichstr, int whichval,
69                          int rw, const char *rwstr) {
70   int donehead= 0;
71   int fd;
72   
73   for (fd=0; fd<fdarrayused; fd++) {
74     if (!(fdarray[fd].wantstate == whichval && fdarray[fd].wantrw == rw)) continue;
75     fdwantdumprwhead(&donehead,whichstr,rwstr);
76     printf(" %d",fd);
77   }
78   if (restfdwantstate == whichval && restfdwantrw == rw) {
79     fdwantdumprwhead(&donehead,whichstr,rwstr);
80     printf(" %d-",fdarrayused);
81   }
82   if (donehead) printf("\n");
83 }
84
85 static void fdwantdump(const char *whichstr, int whichval, const char *rwunspecstr) {
86   if (rwunspecstr) {
87     fdwantdumprw(whichstr,whichval,tokv_word_read,"read");
88     fdwantdumprw(whichstr,whichval,tokv_word_write,"write");
89     fdwantdumprw(whichstr,whichval,0,rwunspecstr);
90   } else {
91     fdwantdumprw(whichstr,whichval,0,0);
92   }
93 }
94
95 static void truefalsedump(const char *whichstr, int val) {
96   printf("%s: %s\n",whichstr,val?"yes":"no");
97 }
98
99 void debug_dumprequest(pid_t mypid) {
100   int i, fd;
101   
102   printf("server pid: %ld\n"
103          "client pid: %ld\n"
104          "service: `%s'\n"
105          "service user: `%s'\n"
106          "calling user: `%s'\n"
107          "calling cwd: `%s'\n"
108          "calling uid: %ld\n"
109          "calling gids:",
110          (long)mypid, (long)request_mbuf.clientpid,
111          service, serviceuser, logname, cwd,
112          (long)request_mbuf.callinguid);
113   for (i=0; i<request_mbuf.ngids; i++) printf(" %ld",(long)gidarray[i]);
114   printf("\n" "fds:");
115   for (fd=0; fd<fdarrayused; fd++)
116     if (fdarray[fd].iswrite != -1)
117       printf(" %d%s",fd,fdarray[fd].iswrite ? "w" : "r");
118   printf("\n" "arguments:");
119   for (i=0; i<request_mbuf.nargs; i++) printf(" `%s'",argarray[i]);
120   printf("\n" "variables:");
121   for (i=0; i<request_mbuf.nvars; i++)
122     printf(" `%s'=`%s'",defvararray[i][0],defvararray[i][1]);
123   printf("\n");
124   if (getenv("USERVD_SLEEP")) sleep(atoi(getenv("USERVD_SLEEP")));
125 }
126
127 void debug_dumpexecsettings(void) {
128   printf("configuration parsed\n");
129   if (userrcfile) printf("user-rcfile: `%s'\n",userrcfile);
130   else printf("user-rcfile: <none>\n");
131   fdwantdump("required",tokv_word_requirefd,"ERROR");
132   fdwantdump("allowed",tokv_word_allowfd,"either");
133   fdwantdump("ignored",tokv_word_ignorefd,0);
134   fdwantdump("null",tokv_word_nullfd,"both");
135   fdwantdump("rejected",tokv_word_rejectfd,0);
136   printf("execute: ");
137   switch (execute) {
138   case tokv_word_reject: printf("reject"); break;
139   case tokv_word_execute: printf("`%s'",execpath); break;
140   case tokv_word_executefromdirectory: printf("from directory, `%s'",execpath); break;
141   case tokv_word_executefrompath: printf("from path"); break;
142   default: abort();
143   }
144   printf("\n");
145   truefalsedump("set-environment",setenvironment);
146   truefalsedump("suppress-args",suppressargs);
147   truefalsedump("disconnect-hup",disconnecthup);
148   truefalsedump("set-environment",setenvironment);
149   printf("errors: ");
150   switch (ehandling) {
151   case tokv_word_errorstostderr: printf("stderr"); break;
152   case tokv_word_errorstofile: printf("file"); break;
153   case tokv_word_errorstosyslog: printf("syslog %d.%d",ehlogfacility,ehloglevel); break;
154   default: abort();
155   }
156   printf("\n");
157 }
158
159 void debug_dumpparameter(const char *parm, char **values) {
160   printf("config parameter `%s':",parm);
161   while (*values) printf(" `%s'",*values++);
162   printf("\n");
163 }
164
165 static int groupsallin(int na, const gid_t *lista,
166                        int nb, const gid_t *listb) {
167   int i,j;
168   for (i=0; i<na; i++) {
169     for (j=0; j<nb && listb[j] != lista[i]; j++);
170     if (j>=nb) return 0;
171   }
172   return 1;
173 }
174
175 int setgroups(size_t wantsize, const gid_t *wantlist) {
176   int realsize, e;
177   gid_t *reallist;
178
179   realsize= getgroups(0,0); if (realsize == -1) return -1;
180   reallist= malloc(sizeof(gid_t)*realsize); if (!reallist) return -1;
181   if (getgroups(realsize,reallist) != realsize)
182     { e= errno; free(reallist); errno= e; return -1; }
183   if (!groupsallin(wantsize,wantlist,realsize,reallist))
184     { free(reallist); errno= EPERM; return -1; }
185   if (!groupsallin(realsize,reallist,wantsize,wantlist))
186     { free(reallist); errno= EINVAL; return -1; }
187   free(reallist); return 0;
188 }
189
190 pid_t nondebug_fork(void) { return 0; }
191 const char *nondebug_serviceuserdir(const char *ifnondebug) { return SERVICEUSERDIR; }
192
193 #else
194
195 void debug_dumprequest(pid_t mypid) { }
196 void debug_dumpexecsettings(void) { }
197 void debug_dumpparameter(const char *parm, char **values) { }
198 pid_t nondebug_fork(void) { return fork(); }
199 const char *nondebug_serviceuserdir(const char *ifnondebug) { return ifnondebug; }
200
201 #endif