* pinentry/pinentry.c: New variable THIS_PGMNAME.
[pinentry.git] / secmem / util.c
1 /* Quintuple Agent
2  * Copyright (C) 1999 Robert Bihlmeyer <robbe@orcus.priv.at>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #define _GNU_SOURCE 1
20
21 #include <unistd.h>
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "util.h"
34
35 #ifndef TEMP_FAILURE_RETRY
36 #define TEMP_FAILURE_RETRY(expression) \
37   (__extension__                                                              \
38     ({ long int __result;                                                     \
39        do __result = (long int) (expression);                                 \
40        while (__result == -1L && errno == EINTR);                             \
41        __result; }))
42 #endif
43
44 static int uid_set = 0;
45 static uid_t real_uid, file_uid;
46
47 /* write DATA of size BYTES to FD, until all is written or an error occurs */
48 ssize_t xwrite(int fd, const void *data, size_t bytes)
49 {
50   char *ptr;
51   size_t todo;
52   ssize_t written = 0;
53
54   for (ptr = (char *)data, todo = bytes; todo; ptr += written, todo -= written)
55     if ((written = TEMP_FAILURE_RETRY(write(fd, ptr, todo))) < 0)
56       break;
57   return written;
58 }
59
60 #if 0
61 extern int debug;
62
63 int debugmsg(const char *fmt, ...)
64 {
65   va_list va;
66   int ret;
67
68   if (debug) {
69     va_start(va, fmt);
70     fprintf(stderr, "\e[4m");
71     ret = vfprintf(stderr, fmt, va);
72     fprintf(stderr, "\e[24m");
73     va_end(va);
74     return ret;
75   } else
76     return 0;
77 }
78 #endif
79
80 /* initialize uid variables */
81 static void init_uids(void)
82 {
83   real_uid = getuid();
84   file_uid = geteuid();
85   uid_set = 1;
86 }
87
88
89 #if 0 /* Not used. */
90 /* lower privileges to the real user's */
91 void lower_privs()
92 {
93   if (!uid_set)
94     init_uids();
95   if (real_uid != file_uid) {
96 #ifdef HAVE_SETEUID
97     if (seteuid(real_uid) < 0) {
98       perror("lowering privileges failed");
99       exit(EXIT_FAILURE);
100     }
101 #else
102     fprintf(stderr, _("Warning: running q-agent setuid on this system is dangerous\n"));
103 #endif /* HAVE_SETEUID */
104   }
105 }
106 #endif /* if 0 */
107
108 #if 0 /* Not used. */
109 /* raise privileges to the effective user's */
110 void raise_privs()
111 {
112   assert(real_uid >= 0);        /* lower_privs() must be called before this */
113 #ifdef HAVE_SETEUID
114   if (real_uid != file_uid && seteuid(file_uid) < 0) {
115    perror("Warning: raising privileges failed");
116   }
117 #endif /* HAVE_SETEUID */
118 }
119 #endif /* if 0 */
120
121 /* drop all additional privileges */
122 void drop_privs()
123 {
124   if (!uid_set)
125     init_uids();
126   if (real_uid != file_uid) {
127     if (setuid(real_uid) < 0) {
128       perror("dropping privileges failed");
129       exit(EXIT_FAILURE);
130     }
131     file_uid = real_uid;
132   }
133 }