| 1 | /* $Cambridge: exim/src/src/routers/rf_queue_add.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 | * Queue address for transport * |
| 16 | *************************************************/ |
| 17 | |
| 18 | /* This function is called to put an address onto the local or remote transport |
| 19 | queue, as appropriate. When the driver is for verifying only, a transport need |
| 20 | not be set, in which case it doesn't actually matter which queue the address |
| 21 | gets put on. |
| 22 | |
| 23 | The generic uid/gid options are inspected and put into the address if they are |
| 24 | set. For a remote transport, if there are fallback hosts, they are added to the |
| 25 | address. |
| 26 | |
| 27 | Arguments: |
| 28 | addr the address, with the transport field set (if not verify only) |
| 29 | paddr_local pointer to the anchor of the local transport chain |
| 30 | paddr_remote pointer to the anchor of the remote transport chain |
| 31 | rblock the router block |
| 32 | pw password entry if check_local_user was set, or NULL |
| 33 | |
| 34 | Returns: FALSE on error; the only case is failing to get a uid/gid |
| 35 | */ |
| 36 | |
| 37 | BOOL |
| 38 | rf_queue_add(address_item *addr, address_item **paddr_local, |
| 39 | address_item **paddr_remote, router_instance *rblock, struct passwd *pw) |
| 40 | { |
| 41 | addr->p.domain_data = deliver_domain_data; /* Save these values for */ |
| 42 | addr->p.localpart_data = deliver_localpart_data; /* use in the transport */ |
| 43 | |
| 44 | /* Handle a local transport */ |
| 45 | |
| 46 | if (addr->transport != NULL && addr->transport->info->local) |
| 47 | { |
| 48 | ugid_block ugid; |
| 49 | |
| 50 | /* Default uid/gid and transport-time home directory are from the passwd file |
| 51 | when check_local_user is set, but can be overridden by explicit settings. |
| 52 | When getting the home directory out of the password information, set the |
| 53 | flag that prevents expansion later. */ |
| 54 | |
| 55 | if (pw != NULL) |
| 56 | { |
| 57 | addr->uid = pw->pw_uid; |
| 58 | addr->gid = pw->pw_gid; |
| 59 | setflag(addr, af_uid_set|af_gid_set|af_home_expanded); |
| 60 | addr->home_dir = string_copy(US pw->pw_dir); |
| 61 | } |
| 62 | |
| 63 | if (!rf_get_ugid(rblock, addr, &ugid)) return FALSE; |
| 64 | rf_set_ugid(addr, &ugid); |
| 65 | |
| 66 | /* transport_home_directory (in rblock->home_directory) takes priority; |
| 67 | otherwise use the expanded value of router_home_directory. The flag also |
| 68 | tells the transport not to re-expand it. */ |
| 69 | |
| 70 | if (rblock->home_directory != NULL) |
| 71 | { |
| 72 | addr->home_dir = rblock->home_directory; |
| 73 | clearflag(addr, af_home_expanded); |
| 74 | } |
| 75 | else if (addr->home_dir == NULL && testflag(addr, af_home_expanded)) |
| 76 | addr->home_dir = deliver_home; |
| 77 | |
| 78 | addr->current_dir = rblock->current_directory; |
| 79 | |
| 80 | addr->next = *paddr_local; |
| 81 | *paddr_local = addr; |
| 82 | } |
| 83 | |
| 84 | /* For a remote transport, set up the fallback host list, and keep a count of |
| 85 | the total number of addresses routed to remote transports. */ |
| 86 | |
| 87 | else |
| 88 | { |
| 89 | addr->fallback_hosts = rblock->fallback_hostlist; |
| 90 | addr->next = *paddr_remote; |
| 91 | *paddr_remote = addr; |
| 92 | remote_delivery_count++; |
| 93 | } |
| 94 | |
| 95 | DEBUG(D_route) |
| 96 | { |
| 97 | debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n" |
| 98 | " errors_to=%s\n", |
| 99 | (addr->transport == NULL)? US"<unset>" : addr->transport->name, |
| 100 | addr->local_part, addr->domain, addr->p.errors_address); |
| 101 | debug_printf(" domain_data=%s localpart_data=%s\n", addr->p.domain_data, |
| 102 | addr->p.localpart_data); |
| 103 | } |
| 104 | |
| 105 | return TRUE; |
| 106 | } |
| 107 | |
| 108 | /* End of rf_queue_add.c */ |