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