Passed
Push — master ( 8dcc68...34e8da )
by
unknown
23:44 queued 20:40
created

listfolders_handle()   B

Complexity

Conditions 8
Paths 12

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 8
eloc 20
nc 12
nop 0
dl 0
loc 30
rs 8.4444
c 1
b 1
f 0
1
#!/usr/bin/env php
2
<?php
3
/*
4
 * SPDX-License-Identifier: AGPL-3.0-only
5
 * SPDX-FileCopyrightText: Copyright 2007-2013,2015-2016 Zarafa Deutschland GmbH
6
 * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH
7
 *
8
 * This is a small command line tool to list folders of a user store or public
9
 * folder available for synchronization.
10
 */
11
12
define('MAPI_SERVER', 'default:');
13
define('SSLCERT_FILE', null);
14
define('SSLCERT_PASS', null);
15
16
$supported_classes = array (
17
    "IPF.Note"          => "SYNC_FOLDER_TYPE_USER_MAIL",
18
    "IPF.Task"          => "SYNC_FOLDER_TYPE_USER_TASK",
19
    "IPF.Appointment"   => "SYNC_FOLDER_TYPE_USER_APPOINTMENT",
20
    "IPF.Contact"       => "SYNC_FOLDER_TYPE_USER_CONTACT",
21
    "IPF.StickyNote"    => "SYNC_FOLDER_TYPE_USER_NOTE"
22
);
23
24
main();
25
26
function main() {
27
    listfolders_configure();
28
    listfolders_handle();
29
}
30
31
function listfolders_configure() {
32
33
    if (php_sapi_name() != "cli") {
34
        fwrite(STDERR, "This script can only be called from the CLI.\n");
35
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
36
    }
37
38
    if (!function_exists("getopt")) {
39
        echo "PHP Function 'getopt()' not found. Please check your PHP version and settings.\n";
40
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
41
    }
42
43
    require('mapi/mapi.util.php');
44
    require('mapi/mapidefs.php');
45
    require('mapi/mapicode.php');
46
    require('mapi/mapitags.php');
47
    require('mapi/mapiguid.php');
48
}
49
50
function listfolders_handle() {
51
    $shortoptions = "l:h:u:p:c:";
52
    $options = getopt($shortoptions);
53
54
    $mapi = MAPI_SERVER;
55
    $sslcert_file = SSLCERT_FILE;
56
    $sslcert_pass = SSLCERT_PASS;
57
    $user = "SYSTEM";
58
    $pass = "";
59
60
    if (isset($options['h']))
61
        $mapi = $options['h'];
62
63
    // accept a remote user
64
    if (isset($options['u']) && isset($options['p'])) {
65
        $user = $options['u'];
66
        $pass = $options['p'];
67
    }
68
    // accept a certificate and passwort for login
69
    else if (isset($options['c']) && isset($options['p'])) {
70
        $sslcert_file = $options['c'];
71
        $sslcert_pass = $options['p'];
72
    }
73
74
    $zarafaAdmin = listfolders_zarafa_admin_setup($mapi, $user, $pass, $sslcert_file, $sslcert_pass);
75
    if (isset($zarafaAdmin['adminStore']) && isset($options['l'])) {
76
        listfolders_getlist($zarafaAdmin['adminStore'], $zarafaAdmin['session'], trim($options['l']));
77
    }
78
    else {
79
        echo "Usage:\nlistfolders.php [actions] [options]\n\nActions: [-l username]\n\t-l username\tlist folders of user, for public folder use 'SYSTEM'\n\nGlobal options: [-h path] [[-u remoteuser] [-p password]] [[-c certificate_path] [-p password]]\n\t-h path\t\tconnect through <path>, e.g. file:///var/run/socket or https://10.0.0.1:237/grommunio\n\t-u remoteuser\tlogin as authenticated administration user\n\t-c certificate\tlogin with a ssl certificate located in this location, e.g. /etc/zarafa/ssl/client.pem\n\t-p password\tpassword of the remoteuser or certificate\n\n";
80
    }
81
}
82
83
function listfolders_zarafa_admin_setup ($mapi, $user, $pass, $sslcert_file, $sslcert_pass) {
84
    $session = @mapi_logon_zarafa($user, $pass, $mapi, $sslcert_file, $sslcert_pass, 0, 'script', 'script');
1 ignored issue
show
Bug introduced by
The function mapi_logon_zarafa was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

84
    $session = @/** @scrutinizer ignore-call */ mapi_logon_zarafa($user, $pass, $mapi, $sslcert_file, $sslcert_pass, 0, 'script', 'script');
Loading history...
85
86
    if (!$session) {
87
        echo "User '$user' could not login. The script will exit. Errorcode: 0x". sprintf("%x", mapi_last_hresult()) . "\n";
1 ignored issue
show
Bug introduced by
The function mapi_last_hresult was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
        echo "User '$user' could not login. The script will exit. Errorcode: 0x". sprintf("%x", /** @scrutinizer ignore-call */ mapi_last_hresult()) . "\n";
Loading history...
88
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
89
    }
90
91
    $adminStore = null;
92
    $stores = @mapi_getmsgstorestable($session);
1 ignored issue
show
Bug introduced by
The function mapi_getmsgstorestable was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

92
    $stores = @/** @scrutinizer ignore-call */ mapi_getmsgstorestable($session);
Loading history...
93
    $storeslist = @mapi_table_queryallrows($stores, array(PR_ENTRYID, PR_DEFAULT_STORE, PR_MDB_PROVIDER));
1 ignored issue
show
Bug introduced by
The function mapi_table_queryallrows was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

93
    $storeslist = @/** @scrutinizer ignore-call */ mapi_table_queryallrows($stores, array(PR_ENTRYID, PR_DEFAULT_STORE, PR_MDB_PROVIDER));
Loading history...
94
    foreach ($storeslist as $store) {
95
        if (isset($store[PR_DEFAULT_STORE]) && $store[PR_DEFAULT_STORE] == true) {
96
            $adminStore = @mapi_openmsgstore($session, $store[PR_ENTRYID]);
1 ignored issue
show
Bug introduced by
The function mapi_openmsgstore was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
            $adminStore = @/** @scrutinizer ignore-call */ mapi_openmsgstore($session, $store[PR_ENTRYID]);
Loading history...
97
                break;
98
            }
99
    }
100
    $zarafauserinfo['admin'] = 1;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$zarafauserinfo was never initialized. Although not strictly required by PHP, it is generally a good practice to add $zarafauserinfo = array(); before regardless.
Loading history...
101
    $admin = (isset($zarafauserinfo['admin']) && $zarafauserinfo['admin'])?true:false;
102
103
    if (!$stores || !$storeslist || !$adminStore || !$admin) {
104
        echo "There was error trying to log in as admin or retrieving admin info. The script will exit.\n";
105
        exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
106
    }
107
108
    return array("session" => $session, "adminStore" => $adminStore);
109
}
110
111
112
function listfolders_getlist ($adminStore, $session, $user) {
113
    global $supported_classes;
114
115
    if (strtoupper($user) == 'SYSTEM') {
116
        // Find the public store store
117
        $storestables = @mapi_getmsgstorestable($session);
1 ignored issue
show
Bug introduced by
The function mapi_getmsgstorestable was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
        $storestables = @/** @scrutinizer ignore-call */ mapi_getmsgstorestable($session);
Loading history...
118
        $result = @mapi_last_hresult();
1 ignored issue
show
Bug introduced by
The function mapi_last_hresult was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
        $result = @/** @scrutinizer ignore-call */ mapi_last_hresult();
Loading history...
119
120
        if ($result == NOERROR){
121
            $rows = @mapi_table_queryallrows($storestables, array(PR_ENTRYID, PR_MDB_PROVIDER));
1 ignored issue
show
Bug introduced by
The function mapi_table_queryallrows was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

121
            $rows = @/** @scrutinizer ignore-call */ mapi_table_queryallrows($storestables, array(PR_ENTRYID, PR_MDB_PROVIDER));
Loading history...
122
123
            foreach($rows as $row) {
124
                if (isset($row[PR_MDB_PROVIDER]) && $row[PR_MDB_PROVIDER] == ZARAFA_STORE_PUBLIC_GUID) {
125
                    if (!isset($row[PR_ENTRYID])) {
126
                        echo "Public folder are not available.\nIf this is a multi-tenancy system, use -u and -p and login with an admin user of the company.\nThe script will exit.\n";
127
                        exit (1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
128
                    }
129
                    $entryid = $row[PR_ENTRYID];
130
                    break;
131
                }
132
            }
133
        }
134
    }
135
    else
136
        $entryid = @mapi_msgstore_createentryid($adminStore, $user);
1 ignored issue
show
Bug introduced by
The function mapi_msgstore_createentryid was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

136
        $entryid = @/** @scrutinizer ignore-call */ mapi_msgstore_createentryid($adminStore, $user);
Loading history...
137
138
    $userStore = @mapi_openmsgstore($session, $entryid);
1 ignored issue
show
Bug introduced by
The function mapi_openmsgstore was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

138
    $userStore = @/** @scrutinizer ignore-call */ mapi_openmsgstore($session, $entryid);
Loading history...
Comprehensibility Best Practice introduced by
The variable $entryid does not seem to be defined for all execution paths leading up to this point.
Loading history...
139
    $hresult = mapi_last_hresult();
140
141
    // Cache the store for later use
142
    if($hresult != NOERROR) {
143
        echo "Could not open store for '$user'. The script will exit.\n";
144
        exit (1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
145
    }
146
147
    if (strtoupper($user) != 'SYSTEM') {
148
        $inbox = mapi_msgstore_getreceivefolder($userStore);
1 ignored issue
show
Bug introduced by
The function mapi_msgstore_getreceivefolder was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
        $inbox = /** @scrutinizer ignore-call */ mapi_msgstore_getreceivefolder($userStore);
Loading history...
149
        if(mapi_last_hresult() != NOERROR) {
150
            printf("Could not open inbox for %s (0x%08X). The script will exit.\n", $user, mapi_last_hresult());
151
            exit (1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
152
        }
153
        $inboxProps = mapi_getprops($inbox, array(PR_SOURCE_KEY));
1 ignored issue
show
Bug introduced by
The function mapi_getprops was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

153
        $inboxProps = /** @scrutinizer ignore-call */ mapi_getprops($inbox, array(PR_SOURCE_KEY));
Loading history...
154
    }
155
156
    $storeProps = mapi_getprops($userStore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID, PR_IPM_WASTEBASKET_ENTRYID));
157
    $root = @mapi_msgstore_openentry($userStore, null);
1 ignored issue
show
Bug introduced by
The function mapi_msgstore_openentry was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
    $root = @/** @scrutinizer ignore-call */ mapi_msgstore_openentry($userStore, null);
Loading history...
158
    $h_table = @mapi_folder_gethierarchytable($root, CONVENIENT_DEPTH);
1 ignored issue
show
Bug introduced by
The function mapi_folder_gethierarchytable was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

158
    $h_table = @/** @scrutinizer ignore-call */ mapi_folder_gethierarchytable($root, CONVENIENT_DEPTH);
Loading history...
159
    $subfolders = @mapi_table_queryallrows($h_table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_CONTAINER_CLASS, PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, PR_FOLDER_TYPE, PR_ATTR_HIDDEN));
160
161
    echo "Available folders in store '$user':\n" . str_repeat("-", 50) . "\n";
162
    foreach($subfolders as $folder) {
163
        // do not display hidden and search folders
164
        if ((isset($folder[PR_ATTR_HIDDEN]) && $folder[PR_ATTR_HIDDEN]) ||
165
            (isset($folder[PR_FOLDER_TYPE]) && $folder[PR_FOLDER_TYPE] == FOLDER_SEARCH)) {
166
167
            continue;
168
        }
169
170
        // handle some special folders
171
        if ((strtoupper($user) != 'SYSTEM') &&
172
            ((isset($inboxProps[PR_SOURCE_KEY]) && $folder[PR_SOURCE_KEY] == $inboxProps[PR_SOURCE_KEY]) ||
173
            $folder[PR_ENTRYID] == $storeProps[PR_IPM_SENTMAIL_ENTRYID] ||
174
            $folder[PR_ENTRYID] == $storeProps[PR_IPM_WASTEBASKET_ENTRYID])) {
175
176
                $folder[PR_CONTAINER_CLASS] = "IPF.Note";
177
        }
178
179
        if (isset($folder[PR_CONTAINER_CLASS]) && array_key_exists($folder[PR_CONTAINER_CLASS], $supported_classes)) {
180
            echo "Folder name:\t". $folder[PR_DISPLAY_NAME] . "\n";
181
            echo "Folder ID:\t". bin2hex($folder[PR_SOURCE_KEY]) . "\n";
182
            echo "Type:\t\t". $supported_classes[$folder[PR_CONTAINER_CLASS]] . "\n";
183
            echo "\n";
184
        }
185
    }
186
}
187
188
function CheckMapiExtVersion($version = "") {
189
    // compare build number if requested
190
    if (preg_match('/^\d+$/', $version) && strlen($version) > 3) {
191
        $vs = preg_split('/-/', phpversion("mapi"));
192
        return ($version <= $vs[1]);
193
    }
194
195
    if (extension_loaded("mapi")){
196
        if (version_compare(phpversion("mapi"), $version) == -1){
197
            return false;
198
        }
199
    }
200
    else
201
        return false;
202
203
    return true;
204
}
205