-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.c
160 lines (145 loc) · 3.05 KB
/
utils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "onepixd.h"
/*****************************************************
** UTIL_BG -- Go into the background
**
** Parameters:
** dofork -- preform the fork if TRUE
** Returns:
** 0 on success, otherwise errno
** Side Effects:
** Forks
** Detatches from controlling terminal
** Closes standard I/O
** Gets rid of groups
** Notes:
** This has not been validated on all
** operating systems.
*/
int
util_bg(int dofork)
{
int fd, i;
if (dofork == TRUE)
{
i = fork();
if (i < 0)
return errno;
if (i != 0)
exit(0);
}
fd = fileno(stdin);
(void) fflush(stdout);
(void) dup2(fd, fileno(stdout));
(void) fflush(stderr);
(void) dup2(fd, fileno(stderr));
(void) close(fd);
(void) setsid();
#if ! OS_DARWIN
(void) setpgrp();
#endif
return (errno = 0);
}
uid_t
util_getuid(char *user)
{
struct passwd *pw = NULL;
uid_t uid;
if (user == NULL)
return 0;
uid = strtoul(user, NULL, 10);
if (uid > 0)
pw = getpwuid(uid);
if (pw == NULL)
pw = getpwnam(user);
if (pw == NULL)
return 0;
return pw->pw_uid;
}
/*****************************************************
** SETRUNASUSER -- Become this user to run as
**
** Parameters:
** uid -- login name or user-id
** Returns:
** 0 on success, otherwise -1
** On error logs a message.
** Side Effects:
** Changes the real user.
** Notes:
** Does not change the group or drop old groups.
** Does not change the effective user-id
*/
int
setrunasuser(char *userid)
{
pid_t uid;
struct passwd * pw;
char ebuf[BUFSIZ];
if (userid != NULL)
{
if (isdigit((int)*userid))
{
uid = atoi(userid);
}
else
{
pw = getpwnam(userid);
if (pw == NULL)
{
(void) snprintf(ebuf, sizeof ebuf, "%s: %s\n",
userid, "No such user.");
log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
return -1;
}
uid = pw->pw_uid;
}
if (uid == 0)
return -1;
if (setuid(uid) != 0)
{
(void) snprintf(ebuf, sizeof ebuf, "setuid(%d): %s\n",
(int)uid, strerror(errno));
log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
return -1;
}
return 0;
}
(void) snprintf(ebuf, sizeof ebuf, "NULL: Cannot set user-id to NULL.\n");
log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
return -1;
}
/*****************************************************
** WRITE_PID_FILE -- Write a file with the PID number
**
** Parameters:
** pidfile -- /path/filename
** Returns:
** 0 on success, otherwise -1
** On error, logs an error message.
** Side Effects:
** Creates and writes a file
** Notes:
** This file is written as the runasuser user.
** May overwrite an existing file.
*/
int
write_pid_file(char *pidfile)
{
FILE *fp = NULL;
char ebuf[BUFSIZ];
if (pidfile == NULL)
{
(void) snprintf(ebuf, sizeof ebuf, "NULL: /path/filename for PID file was NULL");
log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
return -1;
}
if ((fp = fopen(pidfile, "w+")) != NULL)
{
(void) fprintf(fp, "%d\n", (int)getpid());
(void) fclose(fp);
return 0;
}
(void) snprintf(ebuf, sizeof ebuf, "%s: %s\n", pidfile, strerror(errno));
log_emit(LOG_ERR, NULL, __FILE__, __LINE__, ebuf);
return -1;
}