public function auth($p, $cb)
    {
        if (!isset($p['opts'])) {
            $p['opts'] = 0;
        }

        $query = [
            'authenticate' => 1,
            'user' => $p['user'],
            'nonce' => $p['nonce'],
            'key' => self::getAuthKey($p['user'], $p['password'], $p['nonce']),
        ];
        if ($this->safeMode) {
            static::safeModeEnc($query);
        }
        try {
            $this->request(
                self::OP_QUERY,
                pack('V', $p['opts']) . $p['dbname'] . '.$cmd' . "\x00" . pack('VV', 0, -1)
                . bson_encode($query) . (isset($p['fields']) ? bson_encode($p['fields']) : ''),
                true,
                null,
                function ($conn, $reqId = null) use ($p, $cb) {
                    if (!$conn) {
                        !$cb || $cb(['$err' => 'Connection error.']);
                        return;
                    }
                    $conn->requests[$reqId] = [$p['dbname'], $cb, true];
                }
            );
        } catch (\MongoException $e) {
            Daemon::log('MongoClient exception: ' . $e->getMessage() . ': ' . $e->getTraceAsString());
            if ($cb !== null) {
                $cb([
                    '$err' => $e->getMessage(),
                    '$query' => $query,
                    '$fields' => isset($p['fields']) ? $p['fields'] : null
                ]);
            }
        }
    }