This file is indexed.

/usr/bin/ingo-postfix-policyd is in php-horde-ingo 3.1.3-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/php
<?php
/**
 * Usage: ingo-postfix-policyd [-v]
 *
 * Delegated Postfix SMTPD policy server that enforce's Ingo's
 * blacklist and whitelist rules.  Logging is done through the
 * standard Horde logger.
 *
 * How it works: each time a Postfix SMTP server process is started it
 * connects to the policy service socket, and Postfix runs one
 * instance of this PHP script.  By default, a Postfix SMTP server
 * process terminates after 100 seconds of idle time, or after serving
 * 100 clients. Thus, the cost of starting this script is smoothed out
 * over time.
 *
 * To run this from /etc/postfix/master.cf (if necessary substituting
 * a user that has permissions for your Horde configuration and
 * logfiles for www-data):
 *
 *    policy  unix  -       n       n       -       -       spawn
 *      user=www-data argv=/path/to/horde/ingo/scripts/ingo-postfix-policyd
 *
 * To use this from Postfix SMTPD, use in /etc/postfix/main.cf:
 *
 *    smtpd_recipient_restrictions =
 *  ...
 *  reject_unauth_destination
 *  check_policy_service unix:private/policy
 *  ...
 *
 * NOTE: specify check_policy_service AFTER reject_unauth_destination
 * or else your system can become an open relay.
 *
 * To test this script by hand, execute:
 *
 *    % ingo-postfix-policyd
 *
 * Each query is a bunch of attributes. See
 * http://www.postfix.org/SMTPD_POLICY_README.html and the example
 * greylisting policy daemon for all of the possibilities. This script
 * uses only:
 *
 *    sender=foo@bar.tld
 *    recipient=bar@foo.tld
 *
 * And the query is terminated with an:
 *    [empty line]
 *
 * The policy server script will answer in the same style, with an
 * attribute list followed by a empty line:
 *
 *    action=DUNNO
 *    [empty line]
 *
 * The possible actions are documented at
 * http://www.postfix.org/access.5.html. We return "DUNNO" when the
 * sender/recipient combination doesn't match any blacklist or
 * whitelist rules, OK if the sender is whitelisted, and REJECT if the
 * sender is blacklisted.
 *
 * Copyright 2012-2013 Horde LLC (http://www.horde.org/)
 *
 * See the enclosed file LICENSE for license information (ASL).  If you
 * did not receive this file, see http://www.horde.org/licenses/apache.
 *
 * @category Horde
 * @license  http://www.horde.org/licenses/apache ASL
 * @package  Ingo
 */

$baseFile = __DIR__ . '/../../ingo/lib/Application.php';
if (file_exists($baseFile)) {
    require_once $baseFile;
} else {
    require_once 'PEAR/Config.php';
    require_once PEAR_Config::singleton()
        ->get('horde_dir', null, 'pear.horde.org') . '/ingo/lib/Application.php';
}
Horde_Registry::appInit('ingo', array('cli' => true));

exit('Not updated');

// Initialize authentication manager.
$auth = $injector->getInstance('Horde_Auth')->getAuth();

// Make sure output is unbuffered.
ob_implicit_flush();

// Main loop.
$query = array();
while (!feof(STDIN)) {
    $line = fgets(STDIN);
    if (strpos($line, '=') !== false) {
        list($key, $value) = explode('=', trim($line), 2);
        $query[$key] = $value;
    } elseif ($line == "\n") {
        if (empty($query['request']) || $query['request'] != 'smtpd_access_policy') {
            Horde::logMessage('Unrecognized request: ' . substr(var_export($query, true), 0, 200), 'ERR');
            exit(1);
        }

        Horde::logMessage(var_export($query, true), 'DEBUG');
        $action = smtpd_access_policy($query);
        Horde::logMessage("Action: $action", 'DEBUG');
        echo "action=$action\n\n";
        @ob_flush();
        $query = array();
    } else {
        Horde::logMessage('Ignoring garbage: ' . substr($line, 0, 100), 'INFO');
    }
}

exit(0);

/**
 * Do policy checks
 *
 * @param array $query Query parameter hash
 *
 * @return string The access policy response.
 */
function smtpd_access_policy($query)
{
    static $whitelists = array();
    static $blacklists = array();

    if (empty($query['sender']) || empty($query['recipient'])) {
        return null;
    }

    // Try to determine the Horde username corresponding to the email recipient.
    $user = $query['recipient'];
    $pos = strpos($user, '@');
    if ($pos !== false) {
        $user = substr($user, 0, $pos);
    }

    try {
        $user = Horde::callHook('smtpd_access_policy_username', $query, 'ingo');
    } catch (Horde_Exception_HookNotSet $e) {}

    // Get $user's rules if we don't have them already.
    if (!isset($whitelists[$user])) {
        // Default empty rules.
        $whitelists[$user] = array();
        $blacklists[$user] = array();

        // Retrieve the data.
        $GLOBALS['auth']->setAuth($user, array());
        $GLOBALS['session']->set('ingo', 'current_share', ':' . $user);

        $ingo_storage = $GLOBALS['injector']->getInstance('Ingo_Factory_Storage')->create();

        try {
            $whitelists[$user] = $ingo_storage->retrieve(Ingo_Storage::ACTION_WHITELIST)->getWhitelist();
        } catch (Ingo_Exception $e) {}

        try {
            $bl = $ingo_storage->retrieve(Ingo_Storage::ACTION_BLACKLIST);
            if (!$bl->getBlacklistFolder()) {
                // We will only reject email at delivery time if the user
                // wants blacklisted mail deleted completely, not filed
                // into a separate folder.
                $blacklists[$user] = $bl->getBlacklist();
            }
        } catch (Ingo_Exception $e) {}
    }

    // Check whitelist rules first so that mistaken overlap doesn't
    // result in lost mail.
    if (in_array($query['sender'], $whitelists[$user])) {
        return 'OK';
    } elseif (in_array($query['sender'], $blacklists[$user])) {
        return 'REJECT';
    } else {
        return 'DUNNO';
    }
}