1/*
2 * $Id: uid.c,v 1.14 2005-04-28 20:49:45 bfernhomberg Exp $
3 * code: jeff@univrel.pr.uconn.edu
4 *
5 * These functions are abstracted here, so that all calls for resolving
6 * user/group names can be centrally changed (good for OS dependant calls
7 * across the package).
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif /* HAVE_CONFIG_H */
13
14/* don't compile this file at all unless FORCE_UIDGID is set */
15#ifdef FORCE_UIDGID
16
17#include <stdio.h>
18#include <string.h>
19#include <errno.h>
20#include <atalk/logger.h>
21
22/* functions for username and group */
23#include <pwd.h>
24#include <grp.h>
25#include "uid.h"
26
27#ifdef HAVE_UNISTD_H
28#include <unistd.h>
29#endif /* HAVE_UNISTD_H */
30
31extern uid_t    uuid;
32
33void save_uidgid ( pair )
34uidgidset *pair;
35{
36    pair->uid = geteuid ();
37    pair->gid = getegid ();
38}
39
40void restore_uidgid ( pair )
41uidgidset *pair;
42{
43    uid_t uid
44    gid_t gid;
45
46    uid = geteuid ();
47    gid = getegid ();
48
49    if (uid == pair->uid && gid == pair->gid)
50       return;
51
52    if (seteuid(0) < 0) {
53        LOG(log_error, logtype_afpd, "set_uidgid: Could not switch back to root: %s",
54				strerror(errno));
55    }
56
57    if ( setegid ( pair->gid ) < 0 )
58        LOG(log_error, logtype_afpd, "restore_uidgid: unable to setegid '%s': %s",
59            pair->gid, strerror(errno) );
60
61    if ( seteuid ( pair->uid ) < 0 )
62        LOG(log_error, logtype_afpd, "restore_uidgid: unable to seteuid '%s': %s",
63            pair->uid, strerror(errno) );
64    else
65    	uuid = pair->uid;	/* ugly hack for utommode */
66}
67
68void set_uidgid ( this_volume )
69const struct vol	*this_volume;
70{
71    int		uid, gid;   /* derived ones go in here */
72
73    /* check to see if we have to switch users */
74    uid = user_to_uid ( (this_volume)->v_forceuid);
75    gid = group_to_gid ( (this_volume)->v_forcegid);
76
77    if ((!uid || uid == geteuid()) && (!gid || gid == getegid()))
78       return;
79
80    if ( seteuid(0) < 0) {
81        LOG(log_error, logtype_afpd, "set_uidgid: Could not switch back to root: %s",
82				strerror(errno));
83	return;
84    }
85
86    /* check to see if we have to switch groups */
87    if ( gid ) {
88        if ( setegid ( gid ) < 0 )
89            LOG(log_error, logtype_afpd, "set_uidgid: unable to setegid '%s': %s",
90                (this_volume)->v_forcegid, strerror(errno) );
91    } /* end of checking for (this_volume)->v_forcegid */
92
93    if ( uid) {
94        if ( seteuid ( uid ) < 0 )
95            LOG(log_error, logtype_afpd, "set_uidgid: unable to seteuid '%s': %s",
96                (this_volume)->v_forceuid, strerror(errno) );
97    	else
98    	    uuid = uid;	/* ugly hack for utommode */
99
100    } /* end of checking for (this_volume)->v_forceuid */
101
102} /* end function void set_uidgid ( username, group ) */
103
104int user_to_uid ( username )
105char	*username;
106{
107    struct passwd *this_passwd;
108
109    /* check for anything */
110    if ( !username || strlen ( username ) < 1 ) return 0;
111
112    /* grab the /etc/passwd record relating to username */
113    this_passwd = getpwnam ( username );
114
115    /* return false if there is no structure returned */
116    if (this_passwd == NULL) return 0;
117
118    /* return proper uid */
119    return this_passwd->pw_uid;
120
121} /* end function int user_to_uid ( username ) */
122
123int group_to_gid ( group )
124char	*group;
125{
126    struct group *this_group;
127
128    /* check for anything */
129    if ( !group || strlen ( group ) < 1 ) return 0;
130
131    /* grab the /etc/groups record relating to group */
132    this_group = getgrnam ( group );
133
134    /* return false if there is no structure returned */
135    if (this_group == NULL) return 0;
136
137    /* return proper gid */
138    return this_group->gr_gid;
139
140} /* end function int group_to_gid ( group ) */
141
142#endif /* FORCE_UIDGID */
143