]> git.defcon.no Git - hermes/blob - user.php
Changed list node to provide more data. Added change_pw functionality/node. Changed...
[hermes] / user.php
1 <?php
2 require_once('config.php');
3 require_once('lib/user_functions.php');
4 require_once('lib/common_functions.php');
5 require_once('lib/db_functions.php');
6 require_once('lib/phone_functions.php');
7
8 $config = get_config();
9
10 $config['sql_link'] = @mysql_connect(
11 $config['sql_server'],
12 $config['sql_username'],
13 $config['sql_password']
14 );
15 if ( !$config['sql_link'] )
16 {
17 print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database connection failed.'));
18 exit;
19 }
20
21 //*************************************************************************************
22 switch ( $_SERVER['PATH_INFO'] )
23 {
24 case "/get":
25 // Required GET parameters:
26 // user: authentication username, SIP-username without domain component
27 // domain: Domain/realm of the user. username + '@' + domain == SIP address.
28
29 if ( array_key_exists('user', $_GET) ||
30 ( array_key_exists('username', $_GET) && array_key_exists('domain', $_GET )))
31 {
32 $username = "";
33 $domain = "";
34 if ( array_key_exists('username', $_GET) )
35 {
36 $username = $_GET['username'];
37 $domain = $_GET['domain'];
38 }
39 else
40 {
41 $user = split_sipaddress($_GET['user']);
42 if ( !$user )
43 {
44 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
45 break;
46 }
47 list ( $username, $domain ) = $user;
48 }
49
50 // Now, do funky stuff.
51 /*
52 Test if user exists in both 'kamailio.subscribers' and 'provision.users'
53 * Return 'response' => 'ok', 'type' => 'local', 'user' => complete user object.
54 Test if user exists in 'provision.user' only
55 * Return 'response' => 'ok', 'type' => 'remote', 'user' => complete user object.
56 If user does is neither local nor remote
57 * Return 'response' => 'failed' with 'cause' => 'nonexistant'
58 On failure, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
59
60 */
61 // Dummy-response:
62 $userdata = get_userdata( $username, $domain );
63 if ( $userdata )
64 {
65 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
66 }
67 else
68 {
69 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Request for user ' . $username . '@' . $domain . ' failed.'));
70 }
71 }
72 else
73 print json_encode ( array( 'response' => 'invalid') );
74 break;
75 case "/list":
76 /*
77 Simply list all users in user@domain format
78 Perform a search operation if 'search' exists as a GET-parameter
79 * The search should try to do a "smart search" on SIP-usernames:
80 * Try to search with names in in username@domain format
81 * Do the search with wildcards before and after input text.
82 * The search must be done in the provisioning tables, to be able
83 to match non-local users.
84 * SQL SELECT CONCAT() WHERE CONCAT() must be used *shrug*
85 */
86 $search = null;
87 if ( array_key_exists ( 'search', $_GET ) )
88 $search = $_GET['search']; // TODO: Add some sanitation and input validation!
89 $list = list_users( $search );
90 print json_encode( array( 'response' => 'ok', 'list' => $list ));
91 break;
92 case "/add_local":
93 /*
94 What to do??
95 Required parameters should be...
96 ( username & domain ) | user
97 displayname
98 email
99
100 Verify that domain is local (lookup in the 'kamailio.domain' table.
101 Verify that the username is available (nonexistant for domain in kamilio.subscribers (and provision.users?))
102 * Autocreate password
103 * Add username, domain, email and created password to the 'kamailio.subscriber' table
104 * Get the registrar+port, proxy+port from the 'provision.servers' table.
105 * standard dialplan from configuration.
106 * Add to the 'provision.users' table:
107 username -> username
108 password -> generated password
109 displayname -> displayname
110 domain -> domain
111 registrar -> provision.servers.registrar
112 r_port -> provision.servers.r_port
113 proxy -> provision.servers.proxy
114 p_port -> provision.servers.p_port
115 authid -> username
116 dialplan -> standard dialplan
117 linetext -> username
118 * Return 'response' => 'ok' with a full user object in JSON format.
119 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" on JSON format.
120
121 */
122 // Test required parameters:
123 if (
124 ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) )
125 && array_key_exists( 'displayname', $_GET )
126 && array_key_exists( 'email', $_GET ) )
127 {
128 $username = "";
129 $domain = "";
130 if ( array_key_exists('username', $_GET) )
131 {
132 $username = $_GET['username'];
133 $domain = $_GET['domain'];
134 }
135 else
136 {
137 $user = split_sipaddress($_GET['user']);
138 if ( !$user )
139 {
140 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
141 break;
142 }
143 list ( $username, $domain ) = $user;
144 }
145
146 $password = generate_password();
147 $displayname = $_GET['displayname'];
148 $email = $_GET['email'];
149
150 if ( !is_kamailio_domain( $domain ) )
151 {
152 print json_encode ( array( 'response' => 'failed', 'cause' => 'nxdomain', 'detail' => 'The selected domain is not local' ));
153 break;
154 }
155
156 $servers = get_servers( $domain );
157 if ( !$servers )
158 {
159 print json_encode( array( 'response' => 'failed', 'cause' => 'servfail', 'detail' => 'Servers lookup failed for domain '. $domain ) );
160 break;
161 }
162 $registrar = $servers['registrar'];
163 $r_port = $servers['r_port'];
164 $proxy = $servers['proxy'];
165 $p_port = $servers['p_port'];
166 $authid = $username;
167 $linetext = $username;
168 $dialplan = $config['standard_dialplan'];
169
170 if ( is_provision_user ( $username, $domain ) )
171 {
172 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
173 break;
174 }
175 if ( is_kamailio_subscriber ( $username, $domain ) )
176 {
177 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
178 break;
179 }
180 $kam_res = add_kamailio_subscriber( $username, $domain, $password, $email );
181 if ( !$kam_res )
182 {
183 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add kamailio subscriber.' ) );
184 break;
185 }
186 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
187 if ( !$pro_res )
188 {
189 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
190 delete_kamailio_subscriber( $username, $domain );
191 // Give errormessage, and quit.
192 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning. Rolled back kamailio subscriber' ) );
193 break;
194 }
195 $userdata = get_userdata( $username, $domain );
196 if ( !$userdata )
197 {
198 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
199 delete_kamailio_subscriber( $username, $domain );
200 delete_provision_user( $username, $domain );
201 // Give errormessage, and quit.
202 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
203
204 }
205 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
206 }
207 else
208 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
209 break;
210 case "/add_remote":
211 /*
212 Required parameters should be...
213 ( username & domain ) | user
214 displayname
215 password
216 registrar
217 Optional parameters
218 r_port
219 proxy
220 p_port
221 authid
222 dialplan
223 linetext
224
225 Verify that the domain is not a local kamailio domain (REMOTE user..)
226 Verify that the username+domain is not already registered in 'provision.users'.
227 * If r_port is empty, set to 5060
228 * If proxy/port is empty, set to registrar/port
229 * If authid is empty, set to username
230 * If dialplan is empty, set to standard dialplan
231 * If linetext is empty, set to username@domain
232 * Add to the 'provision.users' table:
233 username -> username
234 password -> supplied password
235 displayname -> displayname
236 domain -> domain
237 registrar -> registrar
238 r_port -> r_port
239 proxy -> proxy
240 p_port -> p_port
241 authid -> authid
242 dialplan -> dialplan
243 linetext -> linetext
244 * Return 'response' => 'ok' with a full user object in JSON format.
245 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" in JSON format.
246 */
247
248
249 // Test required parameters:
250 if (
251 ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) )
252 && array_key_exists( 'displayname', $_GET )
253 && array_key_exists( 'password', $_GET )
254 && array_key_exists( 'registrar', $_GET ) )
255 {
256 $username = "";
257 $domain = "";
258 if ( array_key_exists('username', $_GET) )
259 {
260 $username = $_GET['username'];
261 $domain = $_GET['domain'];
262 }
263 else
264 {
265 $user = split_sipaddress($_GET['user']);
266 if ( !$user )
267 {
268 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
269 break;
270 }
271 list ( $username, $domain ) = $user;
272 }
273
274 $password = $_GET['password'];
275 $displayname = $_GET['displayname'];
276 $registrar = $_GET['registrar'];
277 $r_port = ( array_key_exists('r_port', $_GET) ) ? $_GET['r_port'] : 5060;
278
279 $proxy = ( array_key_exists('proxy', $_GET) ) ? $_GET['proxy'] : $registrar;
280 $p_port = ( array_key_exists('p_port', $_GET) ) ? $_GET['p_port'] : $r_port;
281 $authid = ( array_key_exists('authid', $_GET) ) ? $_GET['authid'] : $username;
282 $dialplan = ( array_key_exists('dialplan', $_GET) ) ? $_GET['dialplan'] : $config['standard_dialplan'];
283 $linetext = ( array_key_exists('linetext', $_GET) ) ? $_GET['linetext'] : $username . '@' . $domain;
284
285 if ( is_kamailio_domain( $domain ) )
286 {
287 print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' ));
288 break;
289 }
290
291 if ( is_provision_user ( $username, $domain ) )
292 {
293 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
294 break;
295 }
296 if ( is_kamailio_subscriber ( $username, $domain ) )
297 {
298 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
299 break;
300 }
301
302 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
303 if ( !$pro_res )
304 {
305 // Give errormessage, and quit.
306 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning.' ) );
307 break;
308 }
309 $userdata = get_userdata( $username, $domain );
310 if ( !$userdata )
311 {
312 // Rollback data added!
313 delete_provision_user( $username, $domain );
314 // Give errormessage, and quit.
315 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
316
317 }
318 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
319 }
320 else
321 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
322 break;
323 case "/remove":
324 /*
325 Required parameters should be...
326 ( username & domain ) | user
327
328 * Verify that no associations/relations exist in 'provision.phones'
329 * Verify that the user exists in 'provision.users'
330 * Remove from 'provision.users'
331 * Test to see of user exists in 'kamailio.subscriber'.
332 * Remove from 'kamailio.subscribers'
333 * Return response' => 'ok', 'type' => 'local'
334 * If not in 'kamailio.subscribers'
335 * Return response' => 'ok', 'type' => 'remote'
336 * If associations exist, return 'response' => 'failed', 'cause' => 'inuse'
337 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
338 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
339 */
340 if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) )
341 || array_key_exists('user', $_GET) )
342
343 {
344 $username = "";
345 $domain = "";
346 if ( array_key_exists('username', $_GET) )
347 {
348 $username = $_GET['username'];
349 $domain = $_GET['domain'];
350 }
351 else
352 {
353 $user = split_sipaddress($_GET['user']);
354 if ( !$user )
355 {
356 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
357 break;
358 }
359 list ( $username, $domain ) = $user;
360 }
361
362 if ( get_user_phones ( $username, $domain ) )
363 {
364 print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) );
365 break;
366 }
367 if ( is_provision_user( $username, $domain ) || is_kamailio_subscriber( $username, $domain ) )
368 {
369 delete_provision_user( $username, $domain );
370 delete_kamailio_subscriber( $username, $domain );
371 print json_encode( array ( 'response' => 'ok', 'detail' => 'User ' . $username . '@' . $domain . ' deleted.'));
372 break;
373 }
374 else
375 {
376 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Unable to remove nonexistant user.'));
377 break;
378 }
379
380 break;
381
382 }
383 print json_encode ( array( 'response' => 'invalid') );
384 break;
385 case "/change_pw":
386 /*
387 Required parameters should be...
388 ( username & domain ) | user
389 password
390
391 * Verify that no associations/relations exist in 'provision.phones'
392 * Verify that the user exists ...
393 * Test to see of user exists in 'provision.users'
394 * Test to see of user exists in 'kamailio.subscriber'.
395 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
396 * Update user passwords in 'provision' and 'kamailio' as appropriate
397 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
398 */
399 if ( array_key_exists('password', $_GET) &&
400 ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) )
401 || array_key_exists('user', $_GET) ))
402
403 {
404 $username = "";
405 $domain = "";
406 if ( array_key_exists('username', $_GET) )
407 {
408 $username = $_GET['username'];
409 $domain = $_GET['domain'];
410 }
411 else
412 {
413 $user = split_sipaddress($_GET['user']);
414 if ( !$user )
415 {
416 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
417 break;
418 }
419 list ( $username, $domain ) = $user;
420 }
421 $password = $_GET['password'];
422
423 // Check compatibility of password? TODO...
424 // Fetch old password for rollback? TODO...
425 // Verify that user exists for provisioning
426 if ( ! is_provision_user( $username, $domain ) )
427 {
428 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
429 break;
430 }
431 if ( is_provision_user( $username, $domain ) )
432 {
433 print "WTF";
434 // Update provisioning password
435 if (! update_provision_pw( $username, $domain, $password ) )
436 {
437 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update provisioning password' ) );
438 break;
439 }
440 }
441 // Check for user in kamailio
442 if ( is_kamailio_subscriber( $username, $domain ) )
443 {
444 // Update kamailio password
445 if (! update_kamailio_pw( $username, $domain, $password ) )
446 {
447 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio password' ) );
448 break;
449 }
450 }
451 print json_encode( array ( 'response' => 'ok', 'detail' => 'Password changed for user '.$username.'@'.$domain.'.'));
452 break;
453 }
454 else
455 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
456 break;
457
458 case "/update":
459 /*
460 Required parameters should be...
461 ( username & domain ) | user
462
463 * Verify that no associations/relations exist in 'provision.phones'
464 * Verify that the user exists ...
465 * Test to see of user exists in 'provision.users'
466 * Test to see of user exists in 'kamailio.subscriber'.
467 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
468 * Get update parameters, and change as appropriate ;)
469 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
470 */
471 if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) )
472 || array_key_exists('user', $_GET) )
473
474 {
475 $username = "";
476 $domain = "";
477 if ( array_key_exists('username', $_GET) )
478 {
479 $username = $_GET['username'];
480 $domain = $_GET['domain'];
481 }
482 else
483 {
484 $user = split_sipaddress($_GET['user']);
485 if ( !$user )
486 {
487 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
488 break;
489 }
490 list ( $username, $domain ) = $user;
491 }
492 print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) );
493 }
494 else
495 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
496 break;
497 case "/gen_pw":
498 print generate_password();
499 break;
500 default:
501 print json_encode ( array( 'response' => 'invalid') );
502 }
503 mysql_close( $config['sql_link'] );
504 ?>