204058cd21c6bb3e77a39e6655a471866e71d63d
[users/jgh/exim.git] / src / src / routers / rf_get_ugid.c
1 /* $Cambridge: exim/src/src/routers/rf_get_ugid.c,v 1.5 2009/11/16 19:50:38 nm4 Exp $ */
2
3 /*************************************************
4 *     Exim - an Internet mail transport agent    *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2009 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 #include "../exim.h"
11 #include "rf_functions.h"
12
13
14 /*************************************************
15 *            Get uid/gid for a router            *
16 *************************************************/
17
18 /* This function is called by routers to sort out the uid/gid values which are
19 passed with an address for use by local transports.
20
21 Arguments:
22   rblock       the router block
23   addr         the address being worked on
24   ugid         pointer to a ugid block to fill in
25
26 Returns:       TRUE if all goes well, else FALSE
27 */
28
29 BOOL
30 rf_get_ugid(router_instance *rblock, address_item *addr, ugid_block *ugid)
31 {
32 struct passwd *upw = NULL;
33
34 /* Initialize from fixed values */
35
36 ugid->uid = rblock->uid;
37 ugid->gid = rblock->gid;
38 ugid->uid_set = rblock->uid_set;
39 ugid->gid_set = rblock->gid_set;
40 ugid->initgroups = rblock->initgroups;
41
42 /* If there is no fixed uid set, see if there's a dynamic one that can
43 be expanded and possibly looked up. */
44
45 if (!ugid->uid_set && rblock->expand_uid != NULL)
46   {
47   if (route_find_expanded_user(rblock->expand_uid, rblock->name, US"router",
48     &upw, &(ugid->uid), &(addr->message))) ugid->uid_set = TRUE;
49   else return FALSE;
50   }
51
52 /* Likewise for the gid */
53
54 if (!ugid->gid_set && rblock->expand_gid != NULL)
55   {
56   if (route_find_expanded_group(rblock->expand_gid, rblock->name, US"router",
57     &(ugid->gid), &(addr->message))) ugid->gid_set = TRUE;
58   else return FALSE;
59   }
60
61 /* If a uid is set, then a gid must also be available; use one from the passwd
62 lookup if it happened. */
63
64 if (ugid->uid_set && !ugid->gid_set)
65   {
66   if (upw != NULL)
67     {
68     ugid->gid = upw->pw_gid;
69     ugid->gid_set = TRUE;
70     }
71   else
72     {
73     addr->message = string_sprintf("user set without group for %s router",
74       rblock->name);
75     return FALSE;
76     }
77   }
78
79 return TRUE;
80 }
81
82 /* End of rf_get_ugid.c */