1 | #!/usr/bin/env php |
||
2 | <?php |
||
3 | /** |
||
4 | * Admin - Command line interface |
||
5 | * |
||
6 | * @link http://www.egroupware.org |
||
7 | * @package admin |
||
8 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
9 | * @copyright (c) 2006-19 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
||
10 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
||
11 | */ |
||
12 | |||
13 | use EGroupware\Api; |
||
14 | use EGroupware\Api\Framework; |
||
15 | use EGroupware\Api\Vfs; |
||
16 | |||
17 | chdir(dirname(__FILE__)); // to enable our relative pathes to work |
||
18 | |||
19 | if (php_sapi_name() !== 'cli') // security precaution: forbit calling admin-cli as web-page |
||
20 | { |
||
21 | die('<h1>admin-cli.php must NOT be called as web-page --> exiting !!!</h1>'); |
||
22 | } |
||
23 | elseif ($_SERVER['argc'] <= 1 || $_SERVER['argc'] == 2 && in_array($_SERVER['argv'][1], array('-h', '--help'))) |
||
24 | { |
||
25 | usage(); |
||
26 | } |
||
27 | elseif ($_SERVER['argv'][1] == '--exit-codes') |
||
28 | { |
||
29 | list_exit_codes(); |
||
30 | exit(0); |
||
31 | } |
||
32 | else |
||
33 | { |
||
34 | $arguments = $_SERVER['argv']; |
||
35 | array_shift($arguments); |
||
36 | $action = array_shift($arguments); |
||
37 | } |
||
38 | |||
39 | // allow to specify instance by using a username with appended @domain-name |
||
40 | $arg0s = explode(',',@array_shift($arguments)); |
||
41 | @list($user,$domain) = explode('@',$arg0s[0].'@'); |
||
42 | load_egw($user, @$arg0s[1], $domain); |
||
43 | |||
44 | switch($action) |
||
45 | { |
||
46 | case '--edit-user': |
||
47 | return do_edit_user($arg0s); |
||
48 | |||
49 | case '--add-user': // like --edit-account, but always runs addaccount hook |
||
50 | return do_edit_user($arg0s,true); |
||
51 | |||
52 | case '--edit-alias': |
||
53 | case '--edit-forward': |
||
54 | case '--edit-quota': |
||
55 | return do_edit_mail(substr($action, 7), $arg0s); |
||
56 | |||
57 | case '--change-pw': |
||
58 | return do_change_pw($arg0s); |
||
59 | |||
60 | case '--delete-user': |
||
61 | return do_delete_account($arg0s[2],$arg0s[3]); |
||
62 | |||
63 | case '--edit-group': |
||
64 | return do_edit_group($arg0s); |
||
65 | |||
66 | case '--delete-group': |
||
67 | return do_delete_account($arg0s[2],0,false); |
||
68 | |||
69 | case '--allow-app': |
||
70 | case '--deny-app': |
||
71 | return do_account_app($arg0s,$action == '--allow-app'); |
||
72 | |||
73 | case '--change-account-id': |
||
74 | return do_change_account_id($arg0s); |
||
75 | |||
76 | /* ToDo: get this working again |
||
77 | case '--subscribe-other': |
||
78 | return do_subscribe_other($arg0s[2],$arg0s[3]); |
||
79 | */ |
||
80 | case '--check-acl'; |
||
81 | return do_check_acl(); |
||
82 | |||
83 | case '--show-header'; |
||
84 | return run_command(new setup_cmd_showheader($arg0s[2])); |
||
85 | |||
86 | default: |
||
87 | // we allow to call admin_cmd classes directly, if they define the constant SETUP_CLI_CALLABLE |
||
88 | if (substr($action,0,2) == '--' && (class_exists($class = str_replace('-','_',substr($action, 2))) || |
||
89 | class_exists($class = preg_replace('/^--([a-z0-9_]+)-([a-z0-9_]+)$/i', 'EGroupware\\$1\\$2', $action)) || |
||
90 | class_exists($class = preg_replace('/^--([a-z0-9_]+)-([a-z0-9_]+)$/i', 'EGroupware\\$1\\AdminCmds\\$2', $action))) && |
||
91 | is_subclass_of($class,'admin_cmd') && @constant($class.'::SETUP_CLI_CALLABLE')) |
||
92 | { |
||
93 | $args = array(); |
||
94 | $args['domain'] = array_shift($arg0s); // domain must be first argument, to ensure right domain get's selected in header-include |
||
95 | foreach($arg0s as $arg) |
||
96 | { |
||
97 | list($name,$value) = explode('=',$arg,2); |
||
98 | if(property_exists('admin_cmd',$name)) // dont allow to overwrite admin_cmd properties |
||
99 | { |
||
100 | throw new Api\Exception\WrongUserinput(lang("Invalid argument '%1' !!!",$arg),90); |
||
101 | } |
||
102 | if (substr($name,-1) == ']') // allow 1-dim. arrays |
||
103 | { |
||
104 | list($name,$sub) = explode('[',substr($name,0,-1),2); |
||
105 | if (empty($sub)) |
||
106 | { |
||
107 | $args[$name][] = $value; |
||
108 | } |
||
109 | else |
||
110 | { |
||
111 | $args[$name][$sub] = $value; |
||
112 | } |
||
113 | } |
||
114 | else |
||
115 | { |
||
116 | $args[$name] = $value; |
||
117 | } |
||
118 | } |
||
119 | return run_command(new $class($args)); |
||
120 | } |
||
121 | usage($action, 1); |
||
122 | break; |
||
123 | } |
||
124 | exit(0); |
||
125 | |||
126 | /** |
||
127 | * run a command object, after checking for additional arguments: sheduled, requested or comment |
||
128 | * |
||
129 | * Does not return! Echos success or error messsage and exits with either 0 (success) or the numerical error-code |
||
130 | * |
||
131 | * @param admin_cmd $cmd |
||
132 | */ |
||
133 | function run_command(admin_cmd $cmd) |
||
134 | { |
||
135 | global $arguments,$user,$arg0s,$domain; |
||
136 | |||
137 | $skip_checks = false; |
||
138 | while ($arguments && ($extra = array_shift($arguments))) |
||
139 | { |
||
140 | switch($extra) |
||
141 | { |
||
142 | case '--schedule': // schedule the command instead of running it directly |
||
143 | $time = admin_cmd::parse_date(array_shift($arguments)); |
||
144 | break; |
||
145 | |||
146 | case '--requested': // note who requested to run the command |
||
147 | $cmd->requested = 0; |
||
148 | $cmd->requested_email = array_shift($arguments); |
||
149 | break; |
||
150 | |||
151 | case '--comment': // note a comment |
||
152 | $cmd->comment = array_shift($arguments); |
||
153 | break; |
||
154 | |||
155 | case '--remote': // run the command on a remote install |
||
156 | $cmd->remote_id = admin_cmd::parse_remote(array_shift($arguments)); |
||
157 | break; |
||
158 | |||
159 | case '--skip-checks': // do not yet run the checks for scheduled local commands |
||
160 | $skip_checks = true; |
||
161 | break; |
||
162 | |||
163 | case '--try-run': // only run checks |
||
164 | case '--dry-run': // only run checks |
||
165 | $dry_run = true; |
||
166 | break; |
||
167 | |||
168 | case '--header-access': |
||
169 | if ($cmd instanceof setup_cmd) |
||
170 | { |
||
171 | list($user,$pw) = explode(',',array_shift($arguments),2); |
||
172 | $cmd->set_header_secret($user,$pw); |
||
173 | } |
||
174 | break; |
||
175 | |||
176 | default: |
||
177 | //fail(99,lang('Unknown option %1',$extra); |
||
178 | echo lang('Unknown option %1',$extra)."\n\n"; |
||
179 | usage('',99); |
||
180 | break; |
||
181 | } |
||
182 | } |
||
183 | if ($dry_run && $skip_checks) |
||
184 | { |
||
185 | echo lang('You can NOT use --dry-run together with --skip-checks!')."\n\n"; |
||
186 | usage('', 99); |
||
187 | } |
||
188 | //_debug_array($cmd); |
||
189 | try { |
||
190 | $msg = $cmd->run($time, true, $skip_checks, $dry_run); |
||
191 | if (!is_bool($msg) && $msg) print_r($msg); |
||
192 | |||
193 | // cli can NOT clear instance cache of APC(u), as cli uses different shared memory then webserver |
||
194 | // --> we use a webservice call to clear cache (might fail if no domain in specified in webserver_url or on command line) |
||
195 | if (!$dry_run) |
||
196 | { |
||
197 | $url = $GLOBALS['egw_info']['server']['webserver_url'].'/json.php?menuaction=admin.admin_hooks.ajax_clear_cache'; |
||
198 | if ($url[0] == '/') $url = 'http://'.(!empty($domain) && $domain != 'default' ? $domain : 'localhost').$url; |
||
199 | $data = file_get_contents($url, false, Framework::proxy_context($user,$arg0s[1])); |
||
200 | //error_log("file_get_contents('$url') returned ".array2string($data)); |
||
201 | if ($data && strpos($data, '"success"') !== false) |
||
202 | { |
||
203 | //error_log('Instance cache cleared.'); |
||
204 | } |
||
205 | else |
||
206 | { |
||
207 | error_log('You might need to clear the cache for changes to be visiable: Admin >> Clear cache!'); |
||
208 | } |
||
209 | } |
||
210 | } |
||
211 | catch (Api\Exception $e) { |
||
212 | echo "\n".$e->getMessage()."\n\n"; |
||
213 | exit($e->getCode()); |
||
0 ignored issues
–
show
|
|||
214 | } |
||
215 | echo "\n"; |
||
216 | |||
217 | exit(0); |
||
0 ignored issues
–
show
|
|||
218 | } |
||
219 | |||
220 | /** |
||
221 | * callback to authenticate with the user/pw specified on the commandline |
||
222 | * |
||
223 | * @param array &$account account_info with keys 'login', 'passwd' and optional 'passwd_type' |
||
224 | * @return boolean/string true if we allow the access and account is set, a sessionid or false otherwise |
||
225 | */ |
||
226 | function user_pass_from_argv(&$account) |
||
227 | { |
||
228 | $account = array( |
||
229 | 'login' => $GLOBALS['arg0s'][0], |
||
230 | 'passwd' => $GLOBALS['arg0s'][1], |
||
231 | 'passwd_type' => 'text', |
||
232 | ); |
||
233 | //print_r($account); |
||
234 | if (!($sessionid = $GLOBALS['egw']->session->create($account))) |
||
235 | { |
||
236 | //fail(1,lang("Wrong admin-account or -password !!!")); |
||
237 | echo lang("Wrong admin-account or -password !!!")."\n\n"; |
||
238 | usage('',1); |
||
239 | } |
||
240 | if (!$GLOBALS['egw_info']['user']['apps']['admin']) // will be tested by the header too, but whould give html error-message |
||
241 | { |
||
242 | //fail(2,lang("Permission denied !!!")); |
||
243 | echo lang("Permission denied !!!")."\n\n"; |
||
244 | usage('',2); |
||
245 | } |
||
246 | return $sessionid; |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * Start the eGW session, exits on wrong credintials |
||
251 | * |
||
252 | * @param string $user |
||
253 | * @param string $passwd |
||
254 | * @param string $domain |
||
255 | */ |
||
256 | function load_egw($user,$passwd,$domain='default') |
||
257 | { |
||
258 | //echo "load_egw($user,$passwd,$domain)\n"; |
||
259 | $_REQUEST['domain'] = $domain; |
||
260 | $GLOBALS['egw_login_data'] = array( |
||
261 | 'login' => $user, |
||
262 | 'passwd' => $passwd, |
||
263 | 'passwd_type' => 'text', |
||
264 | ); |
||
265 | |||
266 | if (ini_get('session.save_handler') == 'files' && !is_writable(ini_get('session.save_path')) && is_dir('/tmp') && is_writable('/tmp')) |
||
267 | { |
||
268 | ini_set('session.save_path','/tmp'); // regular users may have no rights to apache's session dir |
||
269 | } |
||
270 | |||
271 | $GLOBALS['egw_info'] = array( |
||
272 | 'flags' => array( |
||
273 | 'currentapp' => 'admin', |
||
274 | 'noheader' => true, |
||
275 | 'autocreate_session_callback' => 'user_pass_from_argv', |
||
276 | 'no_exception_handler' => 'cli', |
||
277 | ) |
||
278 | ); |
||
279 | |||
280 | if (substr($user,0,5) != 'root_') |
||
281 | { |
||
282 | include('../header.inc.php'); |
||
283 | } |
||
284 | else |
||
285 | { |
||
286 | $GLOBALS['egw_info']['flags']['currentapp'] = 'login'; |
||
287 | include('../header.inc.php'); |
||
288 | |||
289 | if ($user == 'root_'.$GLOBALS['egw_info']['server']['header_admin_user'] && |
||
290 | _check_pw($GLOBALS['egw_info']['server']['header_admin_password'],$passwd) || |
||
291 | $user == 'root_'.$GLOBALS['egw_domain'][$_GET['domain']]['config_user'] && |
||
292 | _check_pw($GLOBALS['egw_domain'][$_GET['domain']]['config_passwd'],$passwd)) |
||
293 | { |
||
294 | echo "\nRoot access granted!\n"; |
||
295 | Vfs::$is_root = true; |
||
296 | } |
||
297 | else |
||
298 | { |
||
299 | die("Unknown user or password!\n"); |
||
0 ignored issues
–
show
|
|||
300 | } |
||
301 | } |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Check password against a md5 hash or cleartext password |
||
306 | * |
||
307 | * @param string $hash_or_cleartext |
||
308 | * @param string $pw |
||
309 | * @return boolean |
||
310 | */ |
||
311 | function _check_pw($hash_or_cleartext,$pw) |
||
312 | { |
||
313 | return Api\Auth::compare_password($pw, $hash_or_cleartext, |
||
314 | // old header.inc.php allows md5 or plain passwords with out {type} prefix, which takes precedence |
||
315 | preg_match('/^[0-9a-f]{32}$/', $hash_or_cleartext) ? 'md5' : 'plain'); |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Give a usage message and exit |
||
320 | * |
||
321 | * @param string $action =null |
||
322 | * @param int $ret =0 exit-code |
||
323 | */ |
||
324 | function usage($action=null,$ret=0) |
||
325 | { |
||
326 | unset($action); |
||
327 | $cmd = basename($_SERVER['argv'][0]); |
||
328 | echo "Usage: $cmd --command admin-account[@domain],admin-password,options,... [--schedule {YYYY-mm-dd|+1 week|+5 days}] [--requested 'Name <email>'] [--comment 'comment ...'] [--remote {id|name}] [--skip-checks] [--try-run]\n\n"; |
||
329 | |||
330 | echo "\n\t--skip-checks\tdo NOT run checks\n"; |
||
331 | echo "\t--try-run\tonly run checks\n"; |
||
332 | |||
333 | echo "\tAlternativly you can also use a setup user and password by prefixing it with 'root_', eg. 'root_admin' for setup user 'admin'.\n\n"; |
||
334 | |||
335 | echo "--edit-user admin-account[@domain],admin-password,account[=new-account-name],first-name,last-name,password,email,expires{never(default)|YYYY-MM-DD|already},can-change-pw{yes(default)|no},anon-user{yes|no(default)},primary-group{Default(default)|...}[,groups,...][,homedirectory,loginshell]\n"; |
||
336 | echo " Edit or add a user to EGroupware. If you specify groups, they *replace* the exiting memberships! homedirectory+loginshell are supported only for LDAP and must start with a slash!\n"; |
||
337 | echo "--change-pw admin-account[@domain],admin-password,account,password\n"; |
||
338 | echo " Change/set the password for a given user\n"; |
||
339 | echo "--delete-user admin-account[@domain],admin-password,account-to-delete[,account-to-move-data]\n"; |
||
340 | echo " Deletes a user from EGroupware. It's data can be moved to an other user or it get deleted too.\n"; |
||
341 | echo " You can use '--not-existing' for accounts-to-delete, to delete all no (longer) existing users and groups.\n"; |
||
342 | echo "--edit-group admin-account[@domain],admin-password,group[=new-group-name],email[,members,...]\n"; |
||
343 | echo " Edit or add a group to EGroupware. If you specify members, they *replace* the exiting members!\n"; |
||
344 | echo "--delete-group admin-account[@domain],admin-password,group-to-delete\n"; |
||
345 | echo " Deletes a group from EGroupware.\n"; |
||
346 | echo "--allow-app admin-account[@domain],admin-password,account,application,...\n"; |
||
347 | echo "--deny-app admin-account[@domain],admin-password,account,application,...\n"; |
||
348 | echo " Give or deny an account (user or group specified by account name or id) run rights for the given applications.\n"; |
||
349 | echo "--change-account-id admin-account[@domain],admin-password,from1,to1[...,fromN,toN]\n"; |
||
350 | echo " Changes one or more account_id's in the database (make a backup before!).\n"; |
||
351 | echo "--check-acl admin-account[@domain],admin-password\n"; |
||
352 | echo " Deletes ACL entries of not longer existing accounts (make a database backup before! --> setup-cli.php).\n"; |
||
353 | echo "--admin-cmd-check-cats admin-account[@domain],admin-password\n"; |
||
354 | echo " Deletes categories of not longer existing accounts.\n"; |
||
355 | echo "--edit-alias admin-account[@domain],admin-password,account[=acc_id],create-identity(yes,no/default),[+/-]alias1,...\n"; |
||
356 | echo "--edit-forward admin-account[@domain],admin-password,account[=acc_id],mode(forwardOnly),[+/-]forward1,...\n"; |
||
357 | echo "--edit-quota admin-account[@domain],admin-password,account[=acc_id],quota(mb)\n"; |
||
358 | echo " Edit mail account of EGroupware managed mail-server for a given user and optional acc_id (can't be scheduled or try-run)\n"; |
||
359 | echo "--exit-codes admin-account[@domain],admin-password\n"; |
||
360 | echo " List all exit codes of the command line interface\n"; |
||
361 | |||
362 | exit($ret); |
||
0 ignored issues
–
show
|
|||
363 | } |
||
364 | |||
365 | /** |
||
366 | * Edit mail account of EGroupware managed mail-server |
||
367 | * |
||
368 | * @param string $type "alias", "forward", "quota" |
||
369 | * @param array $arg0s admin-account[@domain],admin-password,account[=acc_id],... |
||
370 | * - alias: create-identity(yes,no/default),[+/-]alias1,...aliasN |
||
371 | * - forward: mode(forwardOnly),[+/-]forward1,...forwardN |
||
372 | * - quota: quota(mb) |
||
373 | * @return int 0 on success |
||
374 | */ |
||
375 | function do_edit_mail($type, array $arg0s) |
||
376 | { |
||
377 | array_shift($arg0s); // admin-account |
||
378 | array_shift($arg0s); // admin-pw |
||
379 | list($account, $acc_id) = explode('=', array_shift($arg0s)); |
||
380 | $account_id = is_numeric($account) ? (int)$account : $GLOBALS['egw']->accounts->name2id($account); |
||
381 | if (!$GLOBALS['egw']->accounts->exists($account_id) && !($account_id = $GLOBALS['egw']->accounts->name2id($account))) |
||
382 | { |
||
383 | echo "Unknown user-account '$account'!\n"; |
||
384 | exit(1); |
||
0 ignored issues
–
show
|
|||
385 | } |
||
386 | $found = 0; |
||
387 | foreach($acc_id ? array(Api\Mail\Account::read($acc_id, $account_id)) : |
||
388 | Api\Mail\Account::search($account_id, false) as $account) |
||
389 | { |
||
390 | if (!isset($acc_id) && !Api\Mail\Account::is_multiple($account)) continue; // no need to waste time on personal accounts |
||
391 | |||
392 | $args = $arg0s; |
||
393 | try { |
||
394 | if (!($data = $account->getUserData($account_id))) |
||
395 | { |
||
396 | continue; // not a managed mail-server |
||
397 | } |
||
398 | switch($type) |
||
399 | { |
||
400 | case 'alias': |
||
401 | $create_identity = strtolower(array_shift($args)) === 'yes'; |
||
402 | $delete_identity = $args[0][0] == '-'; |
||
403 | array_modify($data['mailAlternateAddress'], $args); |
||
404 | break; |
||
405 | case 'forward': |
||
406 | $data['deliveryMode'] = strtolower(array_shift($args)) === 'forwardonly' ? Api\Mail\Smtp::FORWARD_ONLY : ''; |
||
407 | array_modify($data['mailForwardingAddress'], $args); |
||
408 | break; |
||
409 | case 'quota': |
||
410 | $data['quotaLimit'] = int($args[0]); |
||
411 | break; |
||
412 | } |
||
413 | $account->saveUserData($account_id, $data); |
||
414 | echo "Data in mail-account (acc_id=$account->acc_id) updated.\n"; |
||
415 | ++$found; |
||
416 | |||
417 | // create identities for all aliases |
||
418 | if ($type == 'alias' && $create_identity && $args) |
||
419 | { |
||
420 | // check if user allready has an identity created for given aliases |
||
421 | foreach(Api\Mail\Account::identities($account, false, 'ident_email', $account_id) as $ident_id => $email) |
||
422 | { |
||
423 | if (($key = array_search($email, $args)) !== false) |
||
424 | { |
||
425 | // delete identities, if "-" is used and email of identity matches given ones and is not standard identity |
||
426 | if ($delete_identity && $ident_id != $account->ident_id) |
||
427 | { |
||
428 | Api\Mail\Account::delete_identity($ident_id); |
||
429 | } |
||
430 | unset($args[$key]); |
||
431 | } |
||
432 | } |
||
433 | // create not existing identities by copying standard identity plus alias as email |
||
434 | foreach($args as $email) |
||
435 | { |
||
436 | $identity = $account->params; |
||
437 | unset($identity['ident_id']); |
||
438 | unset($identity['ident_name']); |
||
439 | $identity['ident_email'] = $email; |
||
440 | $identity['account_id'] = $account_id; // make this a personal identity for $account_id |
||
441 | Api\Mail\Account::save_identity($identity); |
||
442 | } |
||
443 | if ($args) echo "Identity(s) for ".implode(', ', $args)." created.\n"; |
||
444 | } |
||
445 | } |
||
446 | catch(\Exception $e) { |
||
447 | _egw_log_exception($e); |
||
448 | echo $e->getMessage()."\n"; |
||
449 | } |
||
450 | } |
||
451 | if (!$found) |
||
452 | { |
||
453 | echo "No mailserver managed by this EGroupware instance!\n"; |
||
454 | exit(2); |
||
0 ignored issues
–
show
|
|||
455 | } |
||
456 | exit(0); |
||
0 ignored issues
–
show
|
|||
457 | } |
||
458 | |||
459 | /** |
||
460 | * Set, add or remove from array depending on $mod[0][0] being '+', '-' or something else (set) |
||
461 | * |
||
462 | * @param array& $arr |
||
463 | * @param array& $mod eg. ["[email protected]","[email protected]"] will add all given alias to $arr |
||
464 | * on return optional +/- prefix has been removed |
||
465 | * @return array |
||
466 | */ |
||
467 | function array_modify(&$arr, array &$mod) |
||
468 | { |
||
469 | if (!is_array($arr)) $arr = array(); |
||
470 | |||
471 | switch($mod[0][0]) |
||
472 | { |
||
473 | case '-': |
||
474 | $mod[0] = substr($mod[0], 1); |
||
475 | $arr = array_values(array_unique(array_diff($arr, $mod))); |
||
476 | break; |
||
477 | |||
478 | case '+'; |
||
479 | $mod[0] = substr($mod[0], 1); |
||
480 | $arr = array_values(array_unique(array_merge($arr, $mod))); |
||
481 | break; |
||
482 | |||
483 | default: |
||
484 | $arr = array_values(array_unique($mod)); |
||
485 | } |
||
486 | return $arr; |
||
487 | } |
||
488 | |||
489 | /** |
||
490 | * Give or deny an account (user or group specified by account name or id) run rights for the given applications. |
||
491 | * |
||
492 | * @param array $args admin-account[@domain],admin-password,account,application,... |
||
493 | * @param boolean $allow true=allow, false=deny |
||
494 | * @return int 0 on success |
||
495 | */ |
||
496 | function do_account_app($args,$allow) |
||
497 | { |
||
498 | array_shift($args); // admin-account |
||
499 | array_shift($args); // admin-pw |
||
500 | $account = array_shift($args); |
||
501 | |||
502 | include_once(EGW_INCLUDE_ROOT.'/admin/inc/class.admin_cmd_account_app.inc.php'); |
||
503 | run_command(new admin_cmd_account_app($allow,$account,$args)); |
||
504 | } |
||
505 | |||
506 | /** |
||
507 | * Edit or add a group to EGroupware. If you specify members, they *replace* the exiting member! |
||
508 | * 1: 2: 3: 4: 5: |
||
509 | * @param array $args admin-account[@domain],admin-password,group[=new-group-name],email[,members,...] |
||
510 | */ |
||
511 | function do_edit_group($args) |
||
512 | { |
||
513 | array_shift($args); // admin-account |
||
514 | array_shift($args); // admin-pw |
||
515 | list($account,$new_account_name) = explode('=',array_shift($args)); // account[=new-account-name] |
||
516 | |||
517 | $data = array( |
||
518 | 'account_lid' => $new_account_name, |
||
519 | 'account_email' => array_shift($args), |
||
520 | 'account_members' => $args, |
||
521 | ); |
||
522 | try { |
||
523 | admin_cmd::parse_account($account,false); |
||
524 | |||
525 | foreach($data as &$value) // existing account --> empty values mean dont change, not set them empty! |
||
526 | { |
||
527 | if ((string)$value === '') $value = null; |
||
528 | } |
||
529 | } |
||
530 | catch (Exception $e) { // new group |
||
531 | unset($e); // not used |
||
532 | $data['account_lid'] = $account; |
||
533 | $account = false; |
||
534 | } |
||
535 | run_command(new admin_cmd_edit_group($account,$data)); |
||
536 | } |
||
537 | |||
538 | /** |
||
539 | * Change/Set Password for a given user |
||
540 | * 1: 2: 3: 4: |
||
541 | * @param array $args admin-account[@domain],admin-password,account,password |
||
542 | */ |
||
543 | function do_change_pw($args) |
||
544 | { |
||
545 | array_shift($args); // admin-account |
||
546 | array_shift($args); // admin-pw |
||
547 | $account = array_shift($args); // account |
||
548 | $password = array_shift($args); // pw |
||
549 | |||
550 | run_command(new admin_cmd_change_pw($account,$password)); |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * Edit or add a user to EGroupware. If you specify groups, they *replace* the exiting memberships! |
||
555 | * 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12 |
||
556 | * @param array $args admin-account[@domain],admin-password,account[=new-account-name],first-name,last-name,password,email,expires{never(default)|YYYY-MM-DD|already},can-change-pw{true(default)|false},anon-user{true|false(default)},primary-group{Default(default)|...}[,groups,...][,homedirectory,loginshell] |
||
557 | * @param boolean $run_addaccount_hook =null default run hook depending on account existence, true=allways run addaccount hook |
||
558 | */ |
||
559 | function do_edit_user($args,$run_addaccount_hook=null) |
||
560 | { |
||
561 | array_shift($args); // admin-account |
||
562 | array_shift($args); // admin-pw |
||
563 | list($account,$new_account_name) = explode('=',array_shift($args)); // account[=new-account-name] |
||
564 | |||
565 | $data = array(); |
||
566 | // do we need to support ldap only attributes: homedirectory and loginshell |
||
567 | if (($GLOBALS['egw_info']['server']['account_repository'] == 'ldap' || |
||
568 | empty($GLOBALS['egw_info']['server']['account_repository']) && $GLOBALS['egw_info']['server']['auth_type'] == 'ldap') && |
||
569 | $GLOBALS['egw_info']['server']['ldap_extra_attributes'] && count($args) > 9 && // 9 = primary group |
||
570 | ($last_arg = array_pop($dummy=$args)) && $last_arg[0] == '/') // last argument start with a slash |
||
571 | { |
||
572 | $data['loginshell'] = array_pop($args); |
||
573 | $data['homedirectory'] = array_pop($args); |
||
574 | } |
||
575 | $data += array( |
||
576 | 'account_lid' => $new_account_name, |
||
577 | 'account_firstname' => array_shift($args), |
||
578 | 'account_lastname' => array_shift($args), |
||
579 | 'account_passwd' => array_shift($args), |
||
580 | 'account_email' => array_shift($args), |
||
581 | 'account_expires' => array_shift($args), |
||
582 | 'changepassword' => array_shift($args), |
||
583 | 'anonymous' => array_shift($args), |
||
584 | 'account_primary_group' => array_shift($args), |
||
585 | 'account_groups' => $args, |
||
586 | ); |
||
587 | try { |
||
588 | admin_cmd::parse_account($account,true); |
||
589 | |||
590 | foreach($data as &$value) // existing account --> empty values mean dont change, not set them empty! |
||
591 | { |
||
592 | if ((string)$value === '') $value = null; |
||
593 | } |
||
594 | } |
||
595 | catch (Exception $e) { // new account |
||
596 | unset($e); // not used |
||
597 | $data['account_lid'] = $account; |
||
598 | $account = false; |
||
599 | } |
||
600 | run_command(new admin_cmd_edit_user($account,$data,null,$run_addaccount_hook)); |
||
601 | } |
||
602 | |||
603 | /** |
||
604 | * Delete a given acount from eGW |
||
605 | * |
||
606 | * @param int/string $account account-name of -id |
||
607 | * @param int/string $new_user =0 for users only: account to move the entries too |
||
608 | * @param boolean $is_user =true are we called for a user or group |
||
609 | * @return int 0 on success, 2-4 otherwise (see source) |
||
610 | */ |
||
611 | function do_delete_account($account,$new_user=0,$is_user=true) |
||
612 | { |
||
613 | run_command(new admin_cmd_delete_account($account,$new_user,$is_user)); |
||
614 | } |
||
615 | |||
616 | /** |
||
617 | * Deletes ACL entries of not longer existing accounts |
||
618 | * |
||
619 | * @return int 0 allways |
||
620 | */ |
||
621 | function do_check_acl() |
||
622 | { |
||
623 | run_command(new admin_cmd_check_acl()); |
||
624 | } |
||
625 | |||
626 | /** |
||
627 | * Changes one or more account_id's in the database (make a backup before!). |
||
628 | * |
||
629 | * @param array $args admin-account[@domain],admin-password,from1,to1[...,fromN,toN] |
||
630 | * @return int 0 on success |
||
631 | */ |
||
632 | function do_change_account_id($args) |
||
633 | { |
||
634 | if (count($args) < 4) usage(); // 4 means at least user,pw,from1,to1 |
||
635 | |||
636 | $ids2change = array(); |
||
637 | for($n = 2; $n < count($args); $n += 2) |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
|
|||
638 | { |
||
639 | $from = (int)$args[$n]; |
||
640 | $to = (int)$args[$n+1]; |
||
641 | $ids2change[$from] = $to; |
||
642 | } |
||
643 | run_command(new admin_cmd_change_account_id($ids2change)); |
||
644 | } |
||
645 | |||
646 | /** |
||
647 | * List all exit codes used by the command line interface |
||
648 | * |
||
649 | * The list is generated by "greping" this file for thrown exceptions. |
||
650 | * Exceptions have to be in one line, to be recogniced! |
||
651 | */ |
||
652 | function list_exit_codes() |
||
653 | { |
||
654 | error_reporting(error_reporting() & ~E_NOTICE); |
||
655 | |||
656 | if (!function_exists('lang')) |
||
657 | { |
||
658 | function lang($str) |
||
659 | { |
||
660 | return $str; |
||
661 | } |
||
662 | } |
||
663 | |||
664 | $codes = array(); |
||
665 | $files = array('admin-cli.php'); |
||
666 | foreach(scandir(__DIR__.'/inc') as $file) |
||
667 | { |
||
668 | if (substr($file,0,strlen('class.admin_cmd')) == 'class.admin_cmd') |
||
669 | { |
||
670 | $files[] = 'inc/'.$file; |
||
671 | } |
||
672 | } |
||
673 | foreach($files as $file) |
||
674 | { |
||
675 | $content = file_get_contents(__DIR__.'/'.$file); |
||
676 | |||
677 | $matches = null; |
||
678 | if (preg_match_all('/throw new (Api\\\\Exception[\\\\a-z_]*)\((.*),\\s*([0-9]+)\);/mi',$content,$matches)) |
||
679 | { |
||
680 | //echo $file.":\n"; print_r($matches); |
||
681 | foreach($matches[3] as $key => $code) |
||
682 | { |
||
683 | $src = preg_replace('/(self::)?\$[a-z_>-]+/i', "''", $matches[2][$key]); // gives fatal error otherwise |
||
684 | @eval('$src = '.$src.';'); |
||
685 | |||
686 | if (!empty($src) && (!isset($codes[$code]) || !in_array($src, $codes[$code]))) |
||
687 | { |
||
688 | //if (isset($codes[$code])) echo "$file redefines #$code: ".implode(', ', $codes[$code])."\n"; |
||
689 | $codes[$code][] = $src; |
||
690 | } |
||
691 | } |
||
692 | } |
||
693 | } |
||
694 | $codes[0] = 'Ok'; |
||
695 | ksort($codes, SORT_NUMERIC); |
||
696 | foreach($codes as $num => $msgs) |
||
697 | { |
||
698 | echo $num."\t".str_replace("\n","\n\t", implode(', ', (array)$msgs))."\n"; |
||
699 | } |
||
700 | } |
||
701 | |||
702 | /** |
||
703 | * Read the IMAP ACLs |
||
704 | * |
||
705 | * @param array $args admin-account[@domain],admin-password,accout_lid[,pw] |
||
706 | * @return int 0 on success |
||
707 | */ |
||
708 | function do_subscribe_other($account_lid,$pw=null) |
||
709 | { |
||
710 | unset($account_lid, $pw); |
||
711 | /* ToDo: this cant work, not even in 14.x |
||
712 | if (!($account_id = $GLOBALS['egw']->accounts->name2id($account_lid))) |
||
713 | { |
||
714 | throw new Api\Exception\WrongUserinput(lang("Unknown account: %1 !!!",$account_lid),15); |
||
715 | } |
||
716 | $GLOBALS['egw_info']['user'] = array( |
||
717 | 'account_id' => $account_id, |
||
718 | 'account_lid' => $account_lid, |
||
719 | 'passwd' => $pw, |
||
720 | ); |
||
721 | $emailadmin = new emailadmin_bo(); |
||
722 | $user_profile = $emailadmin->getUserProfile('felamimail'); |
||
723 | unset($emailadmin); |
||
724 | |||
725 | $icServer = new cyrusimap(); |
||
726 | //$icServer =& $user_profile->ic_server[0]; |
||
727 | //print_r($icServer); |
||
728 | |||
729 | $icServer->openConnection(!$pw); |
||
730 | |||
731 | $delimiter = $icServer->getHierarchyDelimiter(); |
||
732 | |||
733 | $mailboxes = $icServer->getMailboxes(); |
||
734 | //print_r($mailboxes); |
||
735 | |||
736 | $own_mbox = 'user'.$delimiter.$account_lid; |
||
737 | |||
738 | foreach($mailboxes as $n => $mailbox) |
||
739 | { |
||
740 | // if ($n < 1) continue; |
||
741 | |||
742 | if (substr($mailbox,0,5) != 'user'.$delimiter || substr($mailbox,0,strlen($own_mbox)) == $own_mbox) continue; |
||
743 | |||
744 | if (!$pw) $mailbox = str_replace('INBOX','user'.$delimiter.$account_lid,$mailbox); |
||
745 | |||
746 | //$rights = $icServer->getACL($mailbox); |
||
747 | //echo "getACL($mailbox)\n"; |
||
748 | //foreach($rights as $data) |
||
749 | //{ |
||
750 | // echo $data['USER'].' '.$data['RIGHTS']."\n"; |
||
751 | //} |
||
752 | echo "subscribing $mailbox for $account_lid\n"; |
||
753 | //$icServer->subscribeMailbox($mailbox); |
||
754 | //exit; |
||
755 | }*/ |
||
756 | } |
||
757 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.