Imported Debian patch 0.60.1-1
[hcoop/debian/courier-authlib.git] / numlib / changeuidgid.c
1 /*
2 ** Copyright 1998 - 2002 Double Precision, Inc. See COPYING for
3 ** distribution information.
4 */
5
6 #if HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9 #include <sys/types.h>
10 #if HAVE_UNISTD_H
11 #include <unistd.h>
12 #endif
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <grp.h>
17 #include <pwd.h>
18 #include <errno.h>
19
20 #include "numlib.h"
21
22 static const char rcsid[]="$Id: changeuidgid.c,v 1.2 2003/01/05 04:01:17 mrsam Exp $";
23
24 void libmail_changegroup(gid_t gid)
25 {
26 if ( setgid(gid))
27 {
28 perror("setgid");
29 exit(1);
30 }
31
32 #if HAVE_SETGROUPS
33 if ( getuid() == 0 && setgroups(1, &gid) )
34 {
35 perror("setgroups");
36 exit(1);
37 }
38 #endif
39 }
40
41 void libmail_changeuidgid(uid_t uid, gid_t gid)
42 {
43 libmail_changegroup(gid);
44 if ( setuid(uid))
45 {
46 perror("setuid");
47 exit(1);
48 }
49 }
50
51 void libmail_changeusername(const char *uname, const gid_t *forcegrp)
52 {
53 struct passwd *pw;
54 uid_t changeuid;
55 gid_t changegid;
56
57 /* uname might be a pointer returned from a previous called to getpw(),
58 ** and libc has a problem getting it back.
59 */
60 char *p=malloc(strlen(uname)+1);
61
62 if (!p)
63 {
64 perror("malloc");
65 exit(1);
66 }
67 strcpy(p, uname);
68
69 errno=ENOENT;
70 if ((pw=getpwnam(p)) == 0)
71 {
72 free(p);
73 perror("getpwnam");
74 exit(1);
75 }
76 free(p);
77
78 changeuid=pw->pw_uid;
79
80 if ( !forcegrp ) forcegrp= &pw->pw_gid;
81
82 changegid= *forcegrp;
83
84 if ( setgid( changegid ))
85 {
86 perror("setgid");
87 exit(1);
88 }
89
90 #if HAVE_INITGROUPS
91 if ( getuid() == 0 && initgroups(pw->pw_name, changegid) )
92 {
93 perror("initgroups");
94 exit(1);
95 }
96 #else
97 #if HAVE_SETGROUPS
98 if ( getuid() == 0 && setgroups(1, &changegid) )
99 {
100 perror("setgroups");
101 exit(1);
102 }
103 #endif
104 #endif
105
106 if (setuid(changeuid))
107 {
108 perror("setuid");
109 exit(1);
110 }
111 }