00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <sys/stat.h>
00034 #include <errno.h>
00035 #include <assert.h>
00036
00037 #ifdef HAVE_LIBXML2
00038 #include <libxml/tree.h>
00039 #include <libxml/xpath.h>
00040 #endif
00041
00042 #define MODULE "eurephia::Users"
00043 #include <eurephia_nullsafe.h>
00044 #include <eurephia_context.h>
00045 #include <eurephia_log.h>
00046 #include <eurephia_xml.h>
00047 #include <eurephia_values_struct.h>
00048 #include <eurephiadb_session_struct.h>
00049 #include <eurephiadb_mapping.h>
00050 #include <eurephiadb_driver.h>
00051 #include <certinfo.h>
00052
00053 #include "../argparser.h"
00054 #include "../get_console_input.h"
00055 #include "../parse_certificate_files.h"
00056 #include "../xsltparser.h"
00057
00058
00062 int register_certificate(eurephiaCTX *ctx, int depth, const char *digest,
00063 const char *cname, const char *org, const char *email);
00064
00065
00071 void display_users_help(int page) {
00072 printf("\n%s -- Administer user accounts\n\n", MODULE);
00073
00074 switch( page ) {
00075 case 'l':
00076 printf("The list mode can accept one parameter:\n\n"
00077 " -S | --sort <sort key> Decide the sort order of the user list\n"
00078 "\n"
00079 "Available sort keys are: uid, username, activated, deactivated and lastaccess\n\n");
00080 break;
00081
00082 case 's':
00083 printf("The show mode shows more information about a user account.\n"
00084 "One of the following arguments are required:\n\n"
00085 " -i | --uid Numeric user ID\n"
00086 " -u | --username User name\n"
00087 "\n"
00088 "Optional arguments are:\n\n"
00089 " -l | --lastlog Show users lastlog entries\n"
00090 " -L | --lastlog-details Show a more verbose lastlog\n"
00091 " -a | --attempts Show users failed attempts and blacklisting\n"
00092 " -b | --blacklist Alias for --attempts\n"
00093 "\n");
00094 break;
00095
00096 case 'a':
00097 printf("The activate mode activates an account which not activated or deactivated.\n"
00098 "One of the following arguments are required:\n\n"
00099 " -i | --uid Numeric user ID\n"
00100 " -u | --username User name\n\n");
00101 break;
00102
00103 case 'd':
00104 printf("The deactivate mode deactivates a user account.\n"
00105 "One of the following arguments are required:\n\n"
00106 " -i | --uid Numeric user ID\n"
00107 " -u | --username User name\n\n");
00108 break;
00109
00110 case 'A':
00111 printf("The add user mode registers a new user account.\n"
00112 "Both of the following arguments are required:\n\n"
00113 " -u | --username User name to use for the new account (required)\n"
00114 " -P | --password Assign a new password via the command line.\n\n"
00115 "To register this new account against a certificate you can use the\n"
00116 "following arguments. These arguments cannot be used together.\n\n"
00117 " -C | --certid Use already registered certificate, identified by certid.\n"
00118 " -D | --digest Use already registered certificate, identified by digest.\n"
00119 " -c | --certfile Use the given certificate file and register it along with\n"
00120 " the account.\n"
00121 " -2 | --pkcs12 Certificate file is using the PKCS#12 format.\n\n");
00122 break;
00123
00124 case 'D':
00125 printf("The delete user mode will delete a user account from the database.\n"
00126 "One of the following arguments are required:\n\n"
00127 " -i | --uid Numeric user ID\n"
00128 " -u | --username User name\n\n");
00129 break;
00130
00131 case 'p':
00132 printf("The change password mode is used for changing password for other\n"
00133 "persons than yourself.\n\n"
00134 "One of the following arguments are required:\n\n"
00135 " -i | --uid Numeric user ID\n"
00136 " -u | --username User name\n\n");
00137 break;
00138
00139 default:
00140 printf("Available modes:\n"
00141 " -l | --list List all user accounts\n"
00142 " -s | --show Show user account details\n"
00143 " -a | --activate Activate a user account\n"
00144 " -d | --deactivate Deactivate a user account\n"
00145 " -A | --add Add a new user account\n"
00146 " -D | --delete Delete a user account\n"
00147 " -p | --password Change password on a users account\n"
00148 " -h | --help <mode> Further help for these modes\n\n");
00149 break;
00150 }
00151 }
00152
00153
00165 int help_Users2(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00166 e_options helpargs[] = {
00167 {"--list", "-l", 0},
00168 {"--show", "-s", 0},
00169 {"--activate", "-a", 0},
00170 {"--deactivate", "-d", 0},
00171 {"--add", "-A", 0},
00172 {"--delete", "-D", 0},
00173 {"--password", "-p", 0},
00174 {NULL, NULL, 0}
00175 };
00176
00177 int i = 1;
00178 display_users_help(eurephia_getopt(&i, argc, argv, helpargs));
00179 return 0;
00180 }
00181
00185 void help_Users() {
00186 display_users_help(0);
00187 }
00188
00189
00201 int list_users(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00202 xmlDoc *qrydoc = NULL, *userlist = NULL;
00203 xmlNode *qry_n = NULL, *fmap_n = NULL;
00204 int i = 0, rc = 0;
00205 char *sortkeys = NULL;
00206 const char *xsltparams[] = {"view", "'userlist'", NULL};
00207
00208 e_options listargs[] = {
00209 {"--sort", "-S", 1},
00210 {"--help", "-h", 0},
00211 {NULL, NULL, 0}
00212 };
00213
00214 assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00215
00216
00217 for( i = 1; i < argc; i++ ) {
00218 switch( eurephia_getopt(&i, argc, argv, listargs) ) {
00219 case 'S':
00220 sortkeys = optargs[0];
00221 i++;
00222 break;
00223
00224 case 'h':
00225 display_users_help('l');
00226 return 0;
00227
00228 default:
00229 return 1;
00230 }
00231 }
00232
00233
00234 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &qrydoc, &qry_n);
00235 assert( (qrydoc != NULL) && (qry_n != NULL) );
00236
00237 xmlNewProp(qry_n, (xmlChar *) "mode", (xmlChar *) "view");
00238 xmlNewChild(qry_n, NULL, (xmlChar *) "sortkeys", (xmlChar *)sortkeys);
00239 xmlNewChild(qry_n, NULL, (xmlChar *) "extractFlags", (xmlChar *) "1");
00240
00241 fmap_n = xmlNewChild(qry_n, NULL, (xmlChar *) "fieldMapping", NULL);
00242 assert( fmap_n != NULL );
00243 xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "users");
00244
00245
00246 userlist = eDBadminUserAccount(ctx, qrydoc);
00247 if( eurephiaXML_IsResultMsg(ctx, userlist) ) {
00248 eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, userlist);
00249 if( res->resultType == exmlERROR ) {
00250 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00251 rc = 1;
00252 } else {
00253 rc = 2;
00254 }
00255 free_nullsafe(ctx, res);
00256 } else {
00257 xslt_print_xmldoc(stdout, cfg, userlist, "users.xsl", xsltparams);
00258 rc = 0;
00259 }
00260 xmlFreeDoc(userlist);
00261 xmlFreeDoc(qrydoc);
00262
00263 return rc;
00264 }
00265
00266
00278 int show_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00279 int i, crit_set = 0, lastlog_verb = 0;
00280 long int show_info = USERINFO_user | USERINFO_certs;
00281 xmlDoc *user_xml = NULL, *srch_xml = NULL;
00282 xmlNode *srch_root = NULL, *fmap_n = NULL;
00283 xmlChar flags[34];
00284
00285 #ifdef FIREWALL
00286 const char *xsltparams[] = {"view", NULL, "firewall", "'1'", "view_digest", "'0'", NULL};
00287 #else
00288 const char *xsltparams[] = {"view", NULL, "firewall", "'0'", "view_digest", "'0'", NULL};
00289 #endif
00290
00291 e_options activargs[] = {
00292 {"--uid", "-i", 1},
00293 {"--username", "-u", 1},
00294 {"--lastlog", "-l", 0},
00295 {"--lastlog-details", "-L", 0},
00296 {"--attempts", "-a", 0},
00297 {"--blacklist", "-b", 0},
00298 {"--help", "-h", 0},
00299 {NULL, NULL, 0}
00300 };
00301
00302 assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00303
00304
00305
00306 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &srch_xml, &srch_root);
00307 xmlNewProp(srch_root, (xmlChar*) "mode", (xmlChar *) "view");
00308
00309
00310 fmap_n = xmlNewChild(srch_root, NULL, (xmlChar *) "fieldMapping", NULL);
00311 xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *)"users");
00312
00313
00314 crit_set = 0;
00315 for( i = 1; i < argc; i++ ) {
00316 switch( eurephia_getopt(&i, argc, argv, activargs) ) {
00317 case 'i':
00318 if( atoi_nullsafe(optargs[0]) == 0 ) {
00319 fprintf(stderr, "%s: Invalid user id\n", MODULE);
00320 return 1;
00321 }
00322 xmlNewChild(fmap_n, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
00323 crit_set++;
00324 break;
00325
00326 case 'u':
00327 if( strlen_nullsafe(optargs[0]) < 3 ) {
00328 fprintf(stderr, "%s: User name too short\n", MODULE);
00329 return 1;
00330 }
00331 xmlNewChild(fmap_n, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
00332 crit_set++;
00333 break;
00334
00335 case 'a':
00336 case 'b':
00337 show_info = USERINFO_attempts | USERINFO_blacklist;
00338 break;
00339
00340 case 'L':
00341 lastlog_verb = 1;
00342 case 'l':
00343 show_info = USERINFO_lastlog;
00344 break;
00345
00346 case 'h':
00347 display_users_help('s');
00348 return 0;
00349
00350 default:
00351 return 1;
00352 }
00353 }
00354
00355
00356 if( crit_set == 0 ) {
00357 fprintf(stderr,
00358 "%s: Missing required parameter. You must provide either user id or user name\n",
00359 MODULE);
00360 xmlFreeDoc(srch_xml);
00361 return 1;
00362 }
00363
00364 if( crit_set > 1 ) {
00365 fprintf(stderr,
00366 "%s: You cannot have several search criteria (-i | -u)\n", MODULE);
00367 xmlFreeDoc(srch_xml);
00368 return 1;
00369 }
00370
00371 xmlStrPrintf(flags, 32, (xmlChar *) "%ld%c", show_info, 0);
00372 xmlNewChild(srch_root, NULL, (xmlChar *) "extractFlags", flags);
00373
00374
00375 if( (user_xml = eDBadminUserAccount(ctx, srch_xml)) == NULL ) {
00376 xmlFreeDoc(srch_xml);
00377 fprintf(stderr, "%s: User not found\n", MODULE);
00378 return 1;
00379 }
00380 xmlFreeDoc(srch_xml);
00381
00382 if( eurephiaXML_IsResultMsg(ctx, user_xml) ) {
00383 eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, user_xml);
00384 if( res->resultType == exmlERROR ) {
00385 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00386 free_nullsafe(ctx, res);
00387 xmlFreeDoc(user_xml);
00388 return 1;
00389 }
00390 free_nullsafe(ctx, res);
00391 }
00392
00393 if( show_info & USERINFO_user ) {
00394 xsltparams[1] = "'userinfo'";
00395 xslt_print_xmldoc(stdout, cfg, user_xml, "users.xsl", xsltparams);
00396 }
00397
00398
00399 if( show_info & USERINFO_certs ) {
00400 xsltparams[1] = "''";
00401 xslt_print_xmldoc(stdout, cfg, user_xml, "certificates.xsl", xsltparams);
00402 }
00403
00404
00405 if( show_info & USERINFO_lastlog ) {
00406 xmlNode *user_n = NULL;
00407
00408 xsltparams[1] = "'list'";
00409 if( lastlog_verb ) {
00410 xsltparams[1] = "'details'";
00411 }
00412
00413 user_n = eurephiaXML_getRoot(ctx, user_xml, "UserAccount", 1);
00414 user_n = xmlFindNode(user_n, "Account");
00415 if( user_n == NULL ) {
00416 fprintf(stderr, "Could not retrieve valid data\n");
00417 xmlFreeDoc(user_xml);
00418 return 1;
00419 }
00420
00421 printf("** Lastlog entries for %s\n\n", xmlGetNodeContent(user_n, "username"));
00422
00423 xslt_print_xmldoc(stdout, cfg, user_xml, "lastlog.xsl", xsltparams);
00424 }
00425
00426
00427 if( (show_info & USERINFO_attempts) || (show_info & USERINFO_blacklist) ) {
00428 xsltparams[1] = "'attemptblacklist'";
00429 xslt_print_xmldoc(stdout, cfg, user_xml, "users.xsl", xsltparams);
00430 }
00431
00432
00433 xmlFreeDoc(user_xml);
00434
00435 return 0;
00436 }
00437
00438
00450 int account_activation(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00451 xmlDoc *user_xml = NULL, *update_xml = NULL, *srch_xml = NULL, *tmp_xml = NULL, *res_xml = NULL;
00452 xmlNode *user_n = NULL, *update_n = NULL, *srch_root = NULL, *tmp_n = NULL, *fmap_n = NULL;
00453 eurephiaRESULT *res = NULL;
00454 char *uid_str = NULL, *activated = NULL, *deactivated = NULL, *actmode_str = NULL, *newpwd = NULL;
00455 int i, actmode = 0, rc = 0, crit_set = 0;
00456 xmlChar flags[34];
00457
00458 e_options activargs[] = {
00459 {"--uid", "-i", 1},
00460 {"--username", "-u", 1},
00461 {"--new-password", "-P", 1},
00462 {"--help", "-h", 0},
00463 {NULL, NULL, 0}
00464 };
00465
00466 assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00467
00468 if( (strcmp(argv[0], "--activate") == 0) || (strcmp(argv[0], "-a") == 0) ) {
00469 actmode = 'a';
00470 actmode_str = "activated";
00471 } else if( (strcmp(argv[0], "--deactivate") == 0) || (strcmp(argv[0], "-d") == 0) ) {
00472 actmode = 'd';
00473 actmode_str = "deactivated";
00474 } else if( (strcmp(argv[0], "--delete") == 0) || (strcmp(argv[0], "-D") == 0) ) {
00475 actmode = 'D';
00476 actmode_str = "deleted";
00477 } else if( (strcmp(argv[0], "--password") == 0) || (strcmp(argv[0], "-p") == 0) ) {
00478 actmode = 'p';
00479 actmode_str = "updated with new password";
00480 } else {
00481 fprintf(stderr, "%s: System error - illegal users mode'%s'\n", MODULE, argv[0]);
00482 return 1;
00483 }
00484
00485
00486 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &srch_xml, &srch_root);
00487 xmlNewProp(srch_root, (xmlChar*) "mode", (xmlChar *) "view");
00488
00489
00490 fmap_n = xmlNewChild(srch_root, NULL, (xmlChar *) "fieldMapping", NULL);
00491 xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *)"users");
00492
00493 xmlStrPrintf(flags, 32, (xmlChar *) "%ld%c", USERINFO_user, 0);
00494 xmlNewChild(srch_root, NULL, (xmlChar *) "extractFlags", flags);
00495
00496
00497 crit_set = 0;
00498 for( i = 1; i < argc; i++ ) {
00499 switch( eurephia_getopt(&i, argc, argv, activargs) ) {
00500 case 'i':
00501 if( atoi_nullsafe(optargs[0]) == 0 ) {
00502 fprintf(stderr, "%s: Invalid user id\n", MODULE);
00503 return 1;
00504 }
00505 xmlNewChild(fmap_n, NULL, (xmlChar *)"uid", (xmlChar *) optargs[0]);
00506 crit_set++;
00507 break;
00508
00509 case 'u':
00510 if( strlen_nullsafe(optargs[0]) < 3 ) {
00511 fprintf(stderr, "%s: User name too short\n", MODULE);
00512 return 1;
00513 }
00514 xmlNewChild(fmap_n, NULL, (xmlChar *)"username", (xmlChar *)optargs[0]);
00515 crit_set++;
00516 break;
00517
00518 case 'h':
00519 display_users_help(actmode);
00520 return 0;
00521
00522 case 'P':
00523 newpwd = strdup_nullsafe(optargs[0]);
00524 break;
00525
00526 default:
00527 return 1;
00528 }
00529 }
00530
00531
00532 if( crit_set == 0 ) {
00533 fprintf(stderr,
00534 "%s: Missing required parameter. You must provide either user id or user name\n",
00535 MODULE);
00536 xmlFreeDoc(srch_xml);
00537 return 1;
00538 }
00539
00540 if( crit_set > 1 ) {
00541 fprintf(stderr,
00542 "%s: You cannot have several search criteria (-i | -u)\n", MODULE);
00543 xmlFreeDoc(srch_xml);
00544 return 1;
00545 }
00546
00547
00548 if( (user_xml = eDBadminUserAccount(ctx, srch_xml)) == NULL ) {
00549 xmlFreeDoc(srch_xml);
00550 fprintf(stderr, "%s: User not found\n", MODULE);
00551 return 1;
00552 }
00553 xmlFreeDoc(srch_xml);
00554
00555 if( eurephiaXML_IsResultMsg(ctx, user_xml) ) {
00556 eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, user_xml);
00557 if( res->resultType == exmlERROR ) {
00558 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00559 free_nullsafe(ctx, res);
00560 xmlFreeDoc(user_xml);
00561 return 1;
00562 }
00563 free_nullsafe(ctx, res);
00564 }
00565
00566 user_n = eurephiaXML_getRoot(ctx, user_xml, "UserAccount", 1);
00567 user_n = xmlFindNode(user_n, "Account");
00568 if( user_n == NULL ) {
00569 xmlFreeDoc(user_xml);
00570 fprintf(stderr, "%s: No user account information found\n", MODULE);
00571 return 1;
00572 }
00573 uid_str = xmlGetAttrValue(user_n->properties, "uid");
00574 activated = defaultValue(xmlGetNodeContent(user_n, "activated"), NULL);
00575 deactivated = defaultValue(xmlGetNodeContent(user_n, "deactivated"), NULL);
00576
00577
00578 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &update_xml, &update_n);
00579 assert( (update_xml != NULL) && (update_n != NULL) );
00580 xmlNewProp(update_n, (xmlChar *) "mode", (xmlChar *) "update");
00581 xmlNewProp(update_n, (xmlChar *) "uid", (xmlChar *) uid_str);
00582
00583
00584 update_n = xmlNewChild(update_n, NULL, (xmlChar *) "fieldMapping", NULL);
00585 xmlNewProp(update_n, (xmlChar *) "table", (xmlChar *) "users");
00586
00587 switch( actmode ) {
00588 case 'a':
00589 if( (activated != NULL) && (deactivated == NULL) ) {
00590 printf("%s: User account is already active\n", MODULE);
00591 goto exit;
00592 } else {
00593
00594 xmlNewChild(update_n, NULL,
00595 (xmlChar *) "activated", (xmlChar *) "CURRENT_TIMESTAMP");
00596
00597
00598 tmp_n = xmlNewChild(update_n, NULL,(xmlChar *) "deactivated", NULL);
00599 xmlNewProp(tmp_n, (xmlChar *) "setnull", (xmlChar *) "1");
00600 }
00601
00602
00603 res_xml = eDBadminUserAccount(ctx, update_xml);
00604 break;
00605
00606 case 'd':
00607 if( (activated != NULL) && (deactivated != NULL) ) {
00608 printf("User account is already deactivated\n");
00609 goto exit;
00610 } else if( (activated != NULL) ) {
00611
00612 xmlNewChild(update_n, NULL,
00613 (xmlChar *) "deactivated", (xmlChar *) "CURRENT_TIMESTAMP");
00614
00615 } else {
00616 fprintf(stderr, "%s: User account is not activated yet\n", MODULE);
00617 goto exit;
00618 }
00619
00620
00621 res_xml = eDBadminUserAccount(ctx, update_xml);
00622 break;
00623
00624 case 'p':
00625
00626
00627 if( newpwd == NULL ) {
00628 char *chkpwd = NULL;
00629
00630 newpwd = (char *) malloc_nullsafe(ctx, 66);
00631 assert(newpwd != NULL);
00632 chkpwd = (char *) malloc_nullsafe(ctx, 66);
00633 assert(chkpwd != NULL);
00634
00635 get_console_input(newpwd, 64, "Password for user:", 1);
00636 if( strlen_nullsafe(newpwd) < 4 ) {
00637 free_nullsafe(ctx, newpwd);
00638 free_nullsafe(ctx, chkpwd);
00639 fprintf(stderr, "%s: Password is too short\n", MODULE);
00640 goto exit;
00641 }
00642
00643 get_console_input(chkpwd, 64, "Verify password for user:", 1);
00644 if( strcmp(newpwd, chkpwd) != 0 ) {
00645 free_nullsafe(ctx, newpwd);
00646 free_nullsafe(ctx, chkpwd);
00647 fprintf(stderr, "%s: Passwords didn't match\n", MODULE);
00648 goto exit;
00649 }
00650 free_nullsafe(ctx, chkpwd);
00651 }
00652
00653
00654 tmp_n = xmlNewChild(update_n, NULL, (xmlChar *) "password", (xmlChar *)newpwd);
00655 xmlNewProp(tmp_n, (xmlChar *) "pwhash", (xmlChar *) "none");
00656 res_xml = eDBadminUserAccount(ctx, update_xml);
00657
00658 free_nullsafe(ctx, newpwd);
00659 break;
00660
00661 case 'D':
00662 xmlFreeDoc(update_xml);
00663
00664 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &update_xml, &update_n);
00665 assert( (update_xml != NULL) && (update_n != NULL) );
00666 xmlNewProp(update_n, (xmlChar *) "mode", (xmlChar *) "delete");
00667 xmlNewProp(update_n, (xmlChar *) "uid", (xmlChar *) uid_str);
00668 update_n = xmlNewChild(update_n, NULL, (xmlChar *) "fieldMapping", NULL);
00669 xmlNewProp(update_n, (xmlChar *) "table", (xmlChar *) "users");
00670
00671 res_xml = eDBadminUserAccount(ctx, update_xml);
00672
00673
00674 if( eurephiaXML_IsResultMsg(ctx, res_xml) ) {
00675 res = eurephiaXML_ParseResultMsg(ctx, res_xml);
00676 if( (res == NULL) || (res->resultType == exmlERROR) ) {
00677 free_nullsafe(ctx, res);
00678 break;
00679 }
00680 free_nullsafe(ctx, res);
00681 } else {
00682
00683 break;
00684 }
00685
00686 xmlFreeDoc(update_xml);
00687 eurephiaXML_CreateDoc(ctx, 1, "usercerts", &update_xml, &update_n);
00688 assert( (update_xml != NULL) && (update_n != NULL) );
00689
00690 xmlNewProp(update_n, (xmlChar *) "mode", (xmlChar *) "remove");
00691 update_n = xmlNewChild(update_n, NULL, (xmlChar *) "fieldMapping", NULL);
00692 xmlNewProp(update_n, (xmlChar *) "table", (xmlChar *) "usercerts");
00693 xmlNewChild(update_n, NULL, (xmlChar *) "uid", (xmlChar *) uid_str);
00694
00695 tmp_xml = eDBadminUserCertsLink(ctx, update_xml);
00696 res = eurephiaXML_ParseResultMsg(ctx, tmp_xml);
00697 if( res == NULL ) {
00698 fprintf(stderr, "%s: Failed to remove user <-> certificate link. "
00699 "No results received\n", MODULE);
00700 rc = 0;
00701 } else if( res->resultType == exmlERROR ) {
00702 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00703 } else {
00704 fprintf(stdout, "%s: %s\n", MODULE, res->message);
00705 rc = 1;
00706 }
00707 free_nullsafe(ctx, res);
00708 xmlFreeDoc(tmp_xml);
00709 break;
00710 }
00711
00712 if( eurephiaXML_IsResultMsg(ctx, res_xml) ) {
00713 eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, res_xml);
00714 if( res->resultType == exmlERROR ) {
00715 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00716 rc = 0;
00717 } else {
00718 fprintf(stdout, "%s: %s\n", MODULE, res->message);
00719 rc = 1;
00720 }
00721 free_nullsafe(ctx, res);
00722 } else {
00723 fprintf(stderr, "%s: Unknown error\n", MODULE);
00724 }
00725 xmlFreeDoc(res_xml);
00726
00727 exit:
00728 xmlFreeDoc(user_xml);
00729 xmlFreeDoc(update_xml);
00730 return (rc != 1);
00731 }
00732
00733
00745 int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00746 xmlDoc *user_xml = NULL, *resxml = NULL;
00747 xmlNode *node = NULL, *node2 = NULL;
00748 eurephiaRESULT *res = NULL;
00749 struct stat cert_stat;
00750 int i = 0, certid = 0, uid = 0, certfile_format = CERTFILE_PEM;
00751 char *uname = NULL, *passwd = NULL, *certfile = NULL, *digest = NULL;
00752
00753 e_options addu_args[] = {
00754 {"--username", "-u", 1},
00755 {"--password", "-P", 1},
00756 {"--certid", "-C", 1},
00757 {"--certfile", "-c", 1},
00758 {"--digest", "-D", 1},
00759 {"--pkcs12", "-2", 0},
00760 {"--help", "-h", 0},
00761 {NULL, NULL, 0}
00762 };
00763
00764 assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00765
00766
00767 for( i = 1; i < argc; i++ ) {
00768 switch( eurephia_getopt(&i, argc, argv, addu_args) ) {
00769 case 'u':
00770 if( strlen_nullsafe(optargs[0]) < 3 ) {
00771 fprintf(stderr, "%s: username is too short\n", MODULE);
00772 return 1;
00773 }
00774 uname = optargs[0];
00775 break;
00776
00777 case 'P':
00778 if( strlen_nullsafe(optargs[0]) < 4 ) {
00779 fprintf(stderr, "%s: password is too short\n", MODULE);
00780 return 1;
00781 }
00782 passwd = strdup_nullsafe(optargs[0]);
00783 break;
00784
00785 case 'C':
00786 if( (certid = atoi_nullsafe(optargs[0])) < 1 ) {
00787 fprintf(stderr, "%s: Invalid certid (numeric value > 0)\n", MODULE);
00788 return 1;
00789 }
00790 break;
00791
00792 case 'c':
00793 if( strlen_nullsafe(optargs[0]) < 1 ) {
00794 fprintf(stderr, "%s: certfile is too short\n", MODULE);
00795 return 1;
00796 }
00797 certfile = optargs[0];
00798
00799 if( stat(certfile, &cert_stat) == -1 ) {
00800 fprintf(stderr, "%s: Could not access certfile: %s (%s)\n", MODULE,
00801 certfile, strerror(errno));
00802 return 1;
00803 }
00804
00805 if( cert_stat.st_size == 0 ) {
00806 fprintf(stderr, "%s: certfile '%s' is empty\n", MODULE, certfile);
00807 return 1;
00808 }
00809 break;
00810
00811 case '2':
00812 certfile_format = CERTFILE_PKCS12;
00813 break;
00814
00815 case 'D':
00816 if( strlen_nullsafe(optargs[0]) < 59 ) {
00817 fprintf(stderr, "%s: Certificate digest is too short\n", MODULE);
00818 return 1;
00819 }
00820 digest = optargs[0];
00821 break;
00822
00823 case 'h':
00824 display_users_help('A');
00825 return 0;
00826
00827 default:
00828 return 1;
00829 }
00830 }
00831
00832
00833 if( uname == NULL ) {
00834 fprintf(stderr, "%s: Missing user name\n", MODULE);
00835 return 1;
00836 }
00837
00838 if( ((certid > 0) && (digest != NULL))
00839 || ((certid > 0) && (certfile != NULL))
00840 || ((digest != NULL) && (certfile != NULL)) ) {
00841 fprintf(stderr, "%s: --certid, --certfile and --digest cannot be used together\n", MODULE);
00842 return 1;
00843 }
00844
00845
00846 if( passwd == NULL ) {
00847 char *chkpwd = NULL;
00848
00849 passwd = (char *) malloc_nullsafe(ctx, 66);
00850 assert(passwd != NULL);
00851
00852 chkpwd = (char *) malloc_nullsafe(ctx, 66);
00853 assert(chkpwd != NULL);
00854
00855 get_console_input(passwd, 64, "Password for user:", 1);
00856 if( strlen_nullsafe(passwd) < 4 ) {
00857 free_nullsafe(ctx, passwd);
00858 free_nullsafe(ctx, chkpwd);
00859 fprintf(stderr, "%s: Password is too short\n", MODULE);
00860 return 1;
00861 }
00862
00863 get_console_input(chkpwd, 64, "Verify password for user:", 1);
00864 if( strcmp(passwd, chkpwd) != 0 ) {
00865 free_nullsafe(ctx, passwd);
00866 free_nullsafe(ctx, chkpwd);
00867 fprintf(stderr, "%s: Passwords didn't match\n", MODULE);
00868 return 1;
00869 }
00870 free_nullsafe(ctx, chkpwd);
00871 }
00872
00873
00874 eurephiaXML_CreateDoc(ctx, 1, "UserAccount", &user_xml, &node);
00875 xmlNewProp(node, (xmlChar *) "mode", (xmlChar *) "add");
00876
00877 node = xmlNewChild(node, NULL, (xmlChar *) "fieldMapping", NULL);
00878 xmlNewProp(node, (xmlChar *) "table", (xmlChar *) "users");
00879
00880 xmlNewChild(node, NULL, (xmlChar *) "username", (xmlChar *) uname);
00881 node2 = xmlNewChild(node, NULL, (xmlChar *) "password", (xmlChar *) passwd);
00882 xmlNewProp(node2, (xmlChar *) "pwhash", (xmlChar *) "none");
00883
00884
00885 resxml = eDBadminUserAccount(ctx, user_xml);
00886 xmlFreeDoc(user_xml);
00887 memset(passwd, 0, strlen_nullsafe(passwd));
00888 free_nullsafe(ctx, passwd);
00889 if( (resxml == NULL) || !eurephiaXML_IsResultMsg(ctx, resxml) ) {
00890 fprintf(stderr, "%s: Failed to register the user. Unknown failure.\n", MODULE);
00891 return 1;
00892 }
00893
00894 res = eurephiaXML_ParseResultMsg(ctx, resxml);
00895 if( res == NULL ) {
00896 fprintf(stderr, "%s: Failed to register the user. No results returned.\n", MODULE);
00897 xmlFreeDoc(resxml);
00898 return 1;
00899 } else if( res->resultType == exmlERROR ) {
00900 fprintf(stderr, "%s: %s\n", MODULE, res->message);
00901 xmlFreeDoc(resxml);
00902 free_nullsafe(ctx, res);
00903 return 1;
00904 }
00905
00906 if( xmlStrcmp(res->details->children->name, (xmlChar *) "UserAccount") != 0 ) {
00907 fprintf(stderr, "%s: Invalid result value. User account might be registered\n", MODULE);
00908 xmlFreeDoc(resxml);
00909 free_nullsafe(ctx, res);
00910 return 1;
00911 }
00912
00913 fprintf(stdout, "%s: %s\n", MODULE, res->message);
00914 uid = atoi_nullsafe(xmlGetAttrValue(res->details->properties, "uid"));
00915 xmlFreeDoc(resxml);
00916 free_nullsafe(ctx, res);
00917
00918 if( (digest != NULL) || (certfile != NULL) ) {
00919 if( digest != NULL ) {
00920 xmlDoc *cert_xml = NULL, *certlist = NULL;
00921 xmlNode *cert_n = NULL;
00922 int certcount = 0;
00923
00924
00925 eurephiaXML_CreateDoc(ctx, 1, "certificates", &cert_xml, &cert_n);
00926 assert( (cert_xml != NULL) && (cert_n != NULL) );
00927 xmlNewProp(cert_n, (xmlChar *) "mode", (xmlChar *) "list");
00928 xmlNewChild(cert_n, NULL, (xmlChar *) "sortkeys", (xmlChar *) "certid");
00929
00930 cert_n = xmlNewChild(cert_n, NULL, (xmlChar *) "fieldMapping", NULL);
00931 xmlNewProp(cert_n, (xmlChar *) "table", (xmlChar *) "certificates");
00932 xmlNewChild(cert_n, NULL, (xmlChar *) "digest", (xmlChar *) digest);
00933
00934 certlist = eDBadminCertificate(ctx, cert_xml);
00935 if( certlist == NULL ) {
00936 fprintf(stderr, "%s: Error while looking up certificate info.\n"
00937 "%s: User account is not associated with any certificates\n",
00938 MODULE, MODULE);
00939 xmlFreeDoc(cert_xml);
00940 goto exit;
00941 }
00942 xmlFreeDoc(cert_xml);
00943
00944 cert_n = eurephiaXML_getRoot(ctx, certlist, "certificates", 1);
00945 if( cert_n == NULL ) {
00946 fprintf(stderr, "%s: Could not find certificates root node in XML document. "
00947 "No association done.\n", MODULE);
00948 xmlFreeDoc(certlist);
00949 goto exit;
00950 }
00951 certcount = atoi_nullsafe(xmlGetAttrValue(cert_n->properties, "certificates"));
00952 if( certcount == 0) {
00953 fprintf(stderr, "%s: No certificates was found. No association is done.\n",
00954 MODULE);
00955 xmlFreeDoc(certlist);
00956 goto exit;
00957 } else if( certcount > 1 ) {
00958 fprintf(stderr, "%s: More than one certificates was found. "
00959 "No association is done.\n", MODULE);
00960 xmlFreeDoc(certlist);
00961 goto exit;
00962 }
00963
00964
00965 cert_n = xmlFindNode(cert_n, "certificate");
00966 if( cert_n == NULL ) {
00967 fprintf(stderr, "%s: Could not find certificate node in XML document. "
00968 "No association done.\n", MODULE);
00969 xmlFreeDoc(certlist);
00970 goto exit;
00971 }
00972
00973 certid = atoi_nullsafe(xmlGetAttrValue(cert_n->properties, "certid"));
00974 xmlFreeDoc(certlist);
00975 } else if( certfile != NULL ) {
00976
00977 certinfo *ci = NULL;
00978
00979 ci = Cert_ParseFile(certfile, certfile_format);
00980 if( ci == NULL ) {
00981 fprintf(stderr, "%s: Could not parse the certificate file. "
00982 "No association done.\n", MODULE);
00983 goto exit;
00984 }
00985
00986 certid = register_certificate(ctx, 0, ci->digest, ci->common_name, ci->org, ci->email);
00987 if( certid == 0 ) {
00988 fprintf(stderr, "%s: Failed to register certificate file. No association done.",
00989 MODULE);
00990 }
00991 }
00992 }
00993
00994
00995 if( (certid > 0) && (uid > 0) ) {
00996 xmlDoc *usercert_xml = NULL, *res_xml = NULL;
00997 xmlNode *usercert_n = NULL;
00998 eurephiaRESULT *res = NULL;
00999 xmlChar tmp[66];
01000
01001 memset(&tmp, 0, 66);
01002 eurephiaXML_CreateDoc(ctx, 1, "usercerts", &usercert_xml, &usercert_n);
01003 assert( (usercert_xml != NULL) && (usercert_n != NULL) );
01004
01005 xmlNewProp(usercert_n, (xmlChar *) "mode", (xmlChar *) "register");
01006 usercert_n = xmlNewChild(usercert_n, NULL, (xmlChar *) "fieldMapping", NULL);
01007 xmlNewProp(usercert_n, (xmlChar *) "table", (xmlChar *) "usercerts");
01008
01009 xmlStrPrintf(tmp, 64, (xmlChar *) "%i%c", uid, '\0');
01010 xmlNewChild(usercert_n, NULL, (xmlChar *) "uid", tmp);
01011 xmlStrPrintf(tmp, 64, (xmlChar *) "%i%c", certid, '\0');
01012 xmlNewChild(usercert_n, NULL, (xmlChar *) "certid", tmp);
01013
01014 res_xml = eDBadminUserCertsLink(ctx, usercert_xml);
01015 if( res_xml == NULL ) {
01016 fprintf(stderr, "%s: Failed to register user <-> certificate link\n", MODULE);
01017 goto exit;
01018 }
01019
01020 res = eurephiaXML_ParseResultMsg(ctx, res_xml);
01021 if( res == NULL ) {
01022 fprintf(stderr, "%s: Failed to register user <-> certificate link. "
01023 "No results received\n", MODULE);
01024 } else if( res->resultType == exmlERROR ) {
01025 fprintf(stderr, "%s: %s\n", MODULE, res->message);
01026 }
01027 free_nullsafe(ctx, res);
01028 xmlFreeDoc(res_xml);
01029 }
01030 exit:
01031 return (uid > 0);
01032 }
01033
01034
01046 int cmd_Users(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
01047 char **mode_argv;
01048 int i, mode_argc = 0, rc = 0;
01049 int (*mode_fnc) (eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv);
01050
01051 e_options modeargs[] = {
01052 {"--list", "-l", 0},
01053 {"--show", "-s", 0},
01054 {"--activate", "-a", 0},
01055 {"--deactivate", "-d", 0},
01056 {"--add", "-A", 0},
01057 {"--delete", "-D", 0},
01058 {"--password", "-p", 0},
01059 {"--help", "-h", 0},
01060 {NULL, NULL, 0}
01061 };
01062
01063 assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
01064 mode_fnc = NULL;
01065 for( i = 1; i < argc; i++ ) {
01066 switch( eurephia_getopt(&i, argc, argv, modeargs) ) {
01067 case 'l':
01068 mode_fnc = list_users;
01069 break;
01070
01071 case 's':
01072 mode_fnc = show_user;
01073 break;
01074
01075 case 'a':
01076 mode_fnc = account_activation;
01077 break;
01078
01079 case 'd':
01080 mode_fnc = account_activation;
01081 break;
01082
01083 case 'h':
01084 mode_fnc = help_Users2;
01085 break;
01086
01087 case 'A':
01088 mode_fnc = add_user;
01089 break;
01090
01091 case 'D':
01092 mode_fnc = account_activation;
01093 break;
01094
01095 case 'p':
01096 mode_fnc = account_activation;
01097 break;
01098
01099 default:
01100 break;
01101 }
01102 if( mode_fnc != NULL ) {
01103 break;
01104 }
01105 }
01106
01107
01108 if( mode_fnc == NULL ) {
01109 fprintf(stderr, "Unknown argument. No mode given\n");
01110 return 1;
01111 }
01112
01113
01114 mode_argv = (char **) calloc(sizeof(char *), (argc - i)+2);
01115 assert(mode_argv != NULL);
01116
01117
01118 mode_argc = eurephia_arraycp(i, argc, argv, mode_argv, (argc - i));
01119
01120
01121 rc = mode_fnc(ctx, sess, cfg, mode_argc, mode_argv);
01122 free_nullsafe(ctx, mode_argv);
01123
01124 return rc;
01125 }