usercerts.c

Go to the documentation of this file.
00001 /* usercerts.c  --  eurephiadm usercerts command:
00002  *                  Management of user account <-> certificate links
00003  *
00004  *  GPLv2 only - Copyright (C) 2008 - 2010
00005  *               David Sommerseth <dazo@users.sourceforge.net>
00006  *
00007  *  This program is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU General Public License
00009  *  as published by the Free Software Foundation; version 2
00010  *  of the License.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  *
00021  */
00022 
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <assert.h>
00035 
00036 #ifdef HAVE_LIBXML2
00037 #include <libxml/tree.h>
00038 #include <libxml/xpath.h>
00039 #endif
00040 
00041 #define MODULE "eurephia::UserCerts" 
00042 #include <eurephia_nullsafe.h>
00043 #include <eurephia_context.h>
00044 #include <eurephia_log.h>
00045 #include <eurephia_xml.h>
00046 #include <eurephia_values_struct.h>
00047 #include <eurephiadb_session_struct.h>
00048 #include <eurephiadb_mapping.h>
00049 #include <eurephiadb_driver.h>
00050 #include <certinfo.h>
00051 
00052 #include "../argparser.h"
00053 #include "../xsltparser.h"
00054 
00055 
00061 void display_usercerts_help(int page) {
00062         switch( page ) {
00063         case 'A':
00064                 printf("The add mode will register a new link between a user account and a certificate.\n"
00065                        "\n"
00066                        "     -c | --certid         Required - Certificate ID\n"
00067                        "     -i | --uid            Required - User account ID\n"
00068 #ifdef FIREWALL
00069                        "     -a | --accessprofile  Firewall profile ID to use for this access\n"
00070 #endif
00071                        "\n"
00072                        );
00073                 break;
00074         case 'D':
00075                 printf("The delete mode will delete a link between a user account and a certificate.\n"
00076                        "\n"
00077                        "     -c | --certid         Certificate ID\n"
00078                        "     -i | --uid            User account ID\n"
00079                        "     -n | --uicid          Unique record id of certificate and user account link\n"
00080 #ifdef FIREWALL
00081                        "     -a | --accessprofile  Firewall profile ID\n"
00082 #endif
00083                        "\n"
00084                        );
00085                 break;
00086 
00087         case 'l':
00088                 printf("The list mode will list all registered links between user accounts and certificates.\n"
00089                        "\n"
00090                        "Options:\n"
00091                        "     -S | --sort           Define the sorting of the list\n"
00092                        "\n"
00093                        );
00094                 break;
00095 
00096 #ifdef FIREWALL
00097         case 'S':
00098                 printf("The set-fwprofile mode will update the firewall access profile for "
00099                        "a given user-cert link\n\n"
00100                        "Options: (both required)\n"
00101                        "     -n | --uicid          Unique record id of certificate and user account link\n"
00102                        "     -a | --accessprofile  Firewall profile ID\n"
00103                        "\n");
00104                 break;
00105 #endif
00106 
00107         default:
00108                 printf("Available modes for the usercerts command are:\n\n"
00109                        "     -A | --add            Register a new certificate and user-cert link\n"
00110                        "     -D | --delete         Delete a certificate and user-cert link\n"
00111 #ifdef FIREWALL
00112                        "     -S | --set-fwprofile  Sets the firewall access profile for a user-cert link \n"
00113 #endif
00114                        "     -l | --list           List all registered user-cert links\n"
00115                        "     -h | --help <mode>    Help about a specific mode\n\n");
00116                 break;
00117         }
00118 }
00119 
00120 
00124 void help_UserCerts() {
00125         display_usercerts_help(0);
00126 }
00127 
00128 
00140 int help_UserCerts2(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00141         e_options helpargs[] = {
00142                 {"--list", "-l", 0},
00143                 {"--add", "-A", 0},
00144                 {"--delete", "-D", 0},
00145 #ifdef FIREWALL
00146                 {"--set-fwprofile", "-S", 0},
00147 #endif
00148                 {NULL, NULL, 0}
00149         };
00150 
00151         int i = 1;
00152         display_usercerts_help(eurephia_getopt(&i, argc, argv, helpargs));
00153         return 0;
00154 }
00155 
00156 
00168 int list_usercerts(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00169         xmlDoc *list_xml = NULL, *srch_xml = NULL;
00170         xmlNode *srch_n = NULL, *fmap_n = NULL;
00171         int i = 0;
00172 #ifdef FIREWALL
00173         const char *xsltparams[] = { "firewall", "'1'", NULL};
00174 #else
00175         const char *xsltparams[] = { "firewall", "'0'", NULL};
00176 #endif
00177 
00178         e_options listargs[] = {
00179                 {"--sort", "-S", 1},
00180                 {"--help", "-h", 0},
00181                 {NULL, NULL, 0}
00182         };
00183 
00184         assert( (ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00185 
00186         eurephiaXML_CreateDoc(ctx, 1, "usercerts", &srch_xml, &srch_n);
00187         assert( srch_xml != NULL && srch_n != NULL );
00188         xmlNewProp(srch_n, (xmlChar *) "mode", (xmlChar *) "search");
00189 
00190         fmap_n = xmlNewChild(srch_n, NULL, (xmlChar *) "fieldMapping", NULL);
00191         xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "usercerts");
00192 
00193 
00194         // Parse arguments
00195         for( i = 1; i < argc; i++ ) {
00196                 switch( eurephia_getopt(&i, argc, argv, listargs) ) {
00197                 case 'S':
00198                         xmlNewChild(srch_n, NULL, (xmlChar *) "sortfields", (xmlChar *)optargs[0]);
00199                         break;
00200 
00201                 case 'h':
00202                         display_usercerts_help('l');
00203                         return 0;
00204 
00205                 default:
00206                         return 1;
00207                 }
00208         }
00209 
00210         list_xml = eDBadminUserCertsLink(ctx, srch_xml);
00211         if( list_xml == NULL ) {
00212                 fprintf(stderr, "%s: Error retrieving user/certificate link list\n", MODULE);
00213                 return 1;
00214         }
00215 
00216         xslt_print_xmldoc(stdout, cfg, list_xml, "usercerts.xsl", xsltparams);
00217         xmlFreeDoc(list_xml);
00218         return 0;
00219 }
00220 
00221 
00233 int add_del_usercert(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00234         xmlDoc *usercert_xml = NULL, *resxml = NULL;
00235         xmlNode *usercert_n = NULL;
00236         eurephiaRESULT *res = NULL;
00237         int i = 0, rc = 0, actmode = 0;
00238         char *certid = NULL, *uid = NULL, *uicid = NULL, *actmode_str = NULL, *accessprofile = NULL;
00239 
00240         e_options addargs[] = {
00241                 {"--uid", "-i", 1},
00242                 {"--certid", "-c", 1},
00243                 {"--uicid", "-n", 1},
00244 #ifdef FIREWALL
00245                 {"--accessprofile", "-a", 1},
00246 #endif
00247                 {"--help", "-h", 0},
00248                 {NULL, NULL, 0}
00249         };
00250 
00251         assert( (ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00252 
00253         if( (strcmp(argv[0], "--add") == 0) || (strcmp(argv[0], "-A") == 0) ) {
00254                 actmode = 'A';
00255                 actmode_str = "registered";
00256         } else if( (strcmp(argv[0], "--delete") == 0) || (strcmp(argv[0], "-D") == 0) ) {
00257                 actmode = 'D';
00258                 actmode_str = "deleted";
00259         }
00260 
00261         eurephiaXML_CreateDoc(ctx, 1, "usercerts", &usercert_xml, &usercert_n);
00262         assert( (usercert_xml != NULL) && (usercert_n != NULL) );
00263 
00264         xmlNewProp(usercert_n, (xmlChar *) "mode", (xmlChar *) (actmode == 'D' ? "remove" : "register"));
00265         usercert_n = xmlNewChild(usercert_n, NULL, (xmlChar *) "fieldMapping", NULL);
00266         xmlNewProp(usercert_n, (xmlChar *) "table", (xmlChar *) "usercerts");
00267 
00268         for( i = 1; i < argc; i++ ) {
00269                 switch( eurephia_getopt(&i, argc, argv, addargs) ) {
00270                 case 'i':
00271                         if( atoi_nullsafe(optargs[0]) < 1 ) {
00272                                 fprintf(stderr, "%s: User ID must be a positive number (>0)\n", MODULE);
00273                                 rc = 1;
00274                                 goto exit;
00275                         }
00276                         xmlNewChild(usercert_n, NULL, (xmlChar *) "uid", (xmlChar *) optargs[0]);
00277                         uid = optargs[0];
00278                         break;
00279 
00280                 case 'c':
00281                         if( atoi_nullsafe(optargs[0]) < 1 ) {
00282                                 fprintf(stderr,"%s: Certificate ID must be a positive number (>0)\n",MODULE);
00283                                 rc = 1;
00284                                 goto exit;
00285                         }
00286                         xmlNewChild(usercert_n, NULL, (xmlChar *) "certid", (xmlChar *) optargs[0]);
00287                         certid = optargs[0];
00288                         break;
00289 
00290 #ifdef FIREWALL
00291                 case 'a':
00292                         if( atoi_nullsafe(optargs[0]) < 1 ) {
00293                                 fprintf(stderr, "%s: Firewall profile ID must be a positive number (>0)\n",
00294                                         MODULE);
00295                                 rc = 1;
00296                                 goto exit;
00297                         }
00298                         xmlNewChild(usercert_n, NULL, (xmlChar *) "accessprofile", (xmlChar *) optargs[0]);
00299                         accessprofile = optargs[0];
00300                         break;
00301 #endif
00302                 case 'n':
00303                         if( actmode != 'D' ) {
00304                                 fprintf(stderr, "%s: --uicid cannot be used with --add\n", MODULE);
00305                                 rc = 1;
00306                                 goto exit;
00307                         }
00308                         if( atoi_nullsafe(optargs[0]) < 1 ) {
00309                                 fprintf(stderr, "%s: uicid must be a positive number (>0)\n",
00310                                         MODULE);
00311                                 rc = 1;
00312                                 goto exit;
00313                         }
00314                         xmlNewChild(usercert_n, NULL, (xmlChar *) "uicid", (xmlChar *) optargs[0]);
00315                         uicid = optargs[0];
00316 
00317                         break;
00318 
00319                 case 'h':
00320                         display_usercerts_help(actmode);
00321                         rc = 0;
00322                         goto exit;
00323 
00324                 default:
00325                         rc = 1;
00326                         goto exit;
00327                }
00328         }
00329 
00330         if( (actmode == 'A') && ((certid == NULL) || (uid == NULL)) ) {
00331                 fprintf(stderr, "%s: You must provide both a user ID (--uid) and "
00332                         "a certificate ID (--certid)\n", MODULE);
00333                 rc = 1;
00334                 goto exit;
00335         }
00336 
00337         if( (actmode == 'D') && (certid == NULL) && (uid == NULL)
00338             && (uicid == NULL) && (accessprofile == NULL)) {
00339                 fprintf(stderr, "%s: You must provide at least --uid, --certid, "
00340                         "--uicid or --accessprofile\n", MODULE);
00341                 rc = 1;
00342                 goto exit;
00343         }
00344 
00345         resxml = eDBadminUserCertsLink(ctx, usercert_xml);
00346         if( resxml == NULL ) {
00347                 fprintf(stderr, "%s: Failed to update user <-> certificate link\n", MODULE);
00348                 rc = 1;
00349                 goto exit;
00350         }
00351 
00352         res = eurephiaXML_ParseResultMsg(ctx, resxml);
00353         if( res == NULL ) {
00354                 fprintf(stderr, "%s: Failed to update user <-> certificate link.  No result available.",
00355                         MODULE);
00356         } else {
00357                 if( res->resultType == exmlERROR ) {
00358                         fprintf(stderr, "%s: %s\n", MODULE, res->message);
00359                         rc = 1;
00360                 } else {
00361                         fprintf(stdout, "%s: %s\n", MODULE, res->message);
00362                         rc = 0;
00363                 }
00364         }
00365         free_nullsafe(ctx, res);
00366         xmlFreeDoc(resxml);
00367 
00368  exit:
00369         xmlFreeDoc(usercert_xml);
00370         return rc;
00371 }
00372 
00373 
00374 #ifdef FIREWALL
00375 
00386 int set_fwprofile(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00387         xmlDoc *usercert_xml = NULL, *res_xml = NULL;
00388         xmlNode *usercert_n = NULL, *fmap_n = NULL;
00389         int rc = 0, i = 0;
00390         int accprf = 0, uicid = 0;
00391 
00392         e_options updateargs[] = {
00393                 {"--uicid", "-n", 1},
00394                 {"--accessprofile", "-a", 1},
00395                 {"--help", "-h", 0},
00396                 {NULL, NULL, 0}
00397         };
00398 
00399         // Setup a XML doc which contains information for the update
00400         eurephiaXML_CreateDoc(ctx, 1, "usercerts", &usercert_xml, &usercert_n);
00401         assert( (usercert_xml != NULL) && (usercert_n != NULL) );
00402 
00403         xmlNewProp(usercert_n, (xmlChar *) "mode", (xmlChar *) "update");
00404         fmap_n = xmlNewChild(usercert_n, NULL, (xmlChar *) "fieldMapping", NULL);
00405         xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "usercerts");
00406 
00407         // Parse arguments
00408         for( i = 1; i < argc; i++ ) {
00409                 switch( eurephia_getopt(&i, argc, argv, updateargs) ) {
00410                 case 'a':
00411                         if( atoi_nullsafe(optargs[0]) < 1 ) {
00412                                 fprintf(stderr, "%s: Firewall profile ID must be a positive number (>0)\n",
00413                                         MODULE);
00414                                 rc = 1;
00415                                 goto exit;
00416                         }
00417                         xmlNewChild(fmap_n, NULL, (xmlChar *) "accessprofile", (xmlChar *) optargs[0]);
00418                         accprf = 1; // Access profile is set
00419                         break;
00420 
00421                 case 'n':
00422                         // The uicid value must not be used as a value in the <fieldMapping> tag, but
00423                         // must be an uucid attribute in the <usercerts> tag.  This is the
00424                         // ID to the record we will update.
00425                         uicid = atoi_nullsafe(optargs[0]);
00426                         if( uicid < 1 ) {
00427                                 fprintf(stderr, "%s: uicid must be a positive number (>0)\n",
00428                                         MODULE);
00429                                 rc = 1;
00430                                 goto exit;
00431                         }
00432                         xmlNewProp(usercert_n, (xmlChar *) "uicid", (xmlChar *) optargs[0]);
00433                         break;
00434 
00435                 case 'h':
00436                         display_usercerts_help('S');
00437                         rc = 0;
00438                         goto exit;
00439 
00440                 default:
00441                         rc = 1;
00442                         goto exit;
00443                }
00444         }
00445 
00446         if( (uicid < 1) || (accprf != 1) ) {
00447                 fprintf(stderr, "%s: You must provide --uicid and --accessprofile\n", MODULE);
00448                 rc = 1;
00449                 goto exit;
00450         }
00451 
00452         res_xml = eDBadminUserCertsLink(ctx, usercert_xml);
00453         if( res_xml == NULL ) {
00454                 fprintf(stderr, "%s: Failed to update firewall access profile for user-cert link\n", MODULE);
00455                 rc = 1;
00456                 goto exit;
00457         } else {
00458                 eurephiaRESULT *res = eurephiaXML_ParseResultMsg(ctx, res_xml);
00459                 if( res->resultType == exmlERROR ) {
00460                         fprintf(stderr, "%s: %s\n", MODULE, res->message);
00461                         rc = 1;
00462                 } else {
00463                         fprintf(stdout, "%s: %s\n", MODULE, res->message);
00464                         rc = 0;
00465                 }
00466         }
00467         xmlFreeDoc(res_xml);
00468 
00469  exit:
00470         xmlFreeDoc(usercert_xml);
00471         return rc;
00472 }
00473 #endif
00474 
00475 
00487 int cmd_UserCerts(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
00488         char **mode_argv;
00489         int i, mode_argc = 0, rc = 0;
00490         int (*mode_fnc) (eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv);
00491 
00492         e_options modeargs[] = {
00493                 {"--list", "-l", 0},
00494                 {"--add", "-A", 0},
00495                 {"--delete", "-D", 0},
00496 #ifdef FIREWALL
00497                 {"--set-fwprofile", "-S", 0},
00498 #endif
00499                 {"--help", "-h", 0},
00500                 {NULL, NULL, 0}
00501         };
00502 
00503         assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));
00504         mode_fnc = NULL;
00505         for( i = 1; i < argc; i++ ) {
00506                 switch( eurephia_getopt(&i, argc, argv, modeargs) ) {
00507                 case 'l':
00508                         mode_fnc = list_usercerts;
00509                         break;
00510 
00511                 case 'h':
00512                         mode_fnc = help_UserCerts2;
00513                         break;
00514 
00515                 case 'A':
00516                         mode_fnc = add_del_usercert;
00517                         break;
00518 
00519                 case 'D':
00520                         mode_fnc = add_del_usercert;
00521                         break;
00522 
00523 #ifdef FIREWALL
00524                 case 'S':
00525                         mode_fnc = set_fwprofile;
00526                         break;
00527 #endif
00528 
00529                 default:
00530                         break;
00531                 }
00532                 if( mode_fnc != NULL ) {
00533                         break;
00534                 }
00535         }
00536 
00537         // If we do not have any known mode defined, exit with error
00538         if( mode_fnc == NULL )  {
00539                 fprintf(stderr, "%s: Unknown argument.  No mode given\n", MODULE);
00540                 return 1;
00541         }
00542 
00543         // Allocate memory for our arguments being sent to the mode function
00544         mode_argv = (char **) calloc(sizeof(char *), (argc - i)+2);
00545         assert(mode_argv != NULL);
00546 
00547         // Copy over only the arguments needed for the mode
00548         mode_argc = eurephia_arraycp(i, argc, argv, mode_argv, (argc - i));
00549 
00550         // Call the mode function
00551         rc = mode_fnc(ctx, sess, cfg, mode_argc, mode_argv);
00552         free_nullsafe(ctx, mode_argv);
00553 
00554         return rc;
00555 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines