00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00112
00113
00114
00115 #include <stdio.h>
00116 #include <stdlib.h>
00117 #include <string.h>
00118 #include <pwd.h>
00119 #include <grp.h>
00120 #include <ctype.h>
00121
00122 #include "lcmaps_config.h"
00123 #include "lcmaps_modules.h"
00124 #include "lcmaps_arguments.h"
00125 #include "lcmaps_cred_data.h"
00126
00127
00128
00129
00130 #define MAX_UNDEFINED ((int)(-1))
00131
00132 #ifndef NGROUPS
00133 #ifdef NGROUPS_MAX
00134 #define NGROUPS NGROUPS_MAX
00135 #else
00136 #define NGROUPS 32
00137 #endif
00138 #endif
00139
00140
00141
00142
00143
00144
00145 #ifndef MAX_LOG_BUFFER_SIZE
00146 #define MAX_LOG_BUFFER_SIZE 500
00147 #endif
00148
00149
00150
00151
00152
00153 static int log_cred (
00154 char *dn,
00155 uid_t *uid,
00156 int cntUid,
00157 gid_t *priGid,
00158 int cntPriGid,
00159 gid_t *secGid,
00160 int cntSecGid
00161 );
00162
00163
00164
00165
00166
00167
00168 static int maxuid = MAX_UNDEFINED;
00169 static int maxpgid = MAX_UNDEFINED;
00170 static int maxsgid = MAX_UNDEFINED;
00171 static int set_only_euid = 0;
00172 static int set_only_egid = 0;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 static int log_cred (char *dn,
00194 uid_t *uid,
00195 int cntUid,
00196 gid_t *priGid,
00197 int cntPriGid,
00198 gid_t *secGid,
00199 int cntSecGid)
00200 {
00201 char * logstr = "\tlcmaps_plugin_posix_enf-log_cred()";
00202
00203 struct passwd * user_info = NULL;
00204 struct group * grp_info = NULL;
00205
00206 char * logbuf;
00207 char * strname;
00208 int i;
00209 int ngroups;
00210 gid_t * list;
00211
00212 int logbufcnt = 0;
00213
00214
00215 logbuf = malloc(MAX_LOG_BUFFER_SIZE * sizeof(char));
00216
00217 strcpy (logbuf, "uid=");
00218 logbufcnt += strlen(logbuf);
00219 for (i = 0; i < cntUid; i++)
00220 {
00221 uid_t found_uid=-1;
00222
00223 if (set_only_euid)
00224 found_uid = geteuid();
00225 else
00226 found_uid = getuid();
00227 user_info = getpwuid(found_uid);
00228
00229 if (user_info != NULL)
00230 logbufcnt += strlen(strname = strdup(user_info->pw_name));
00231 else
00232 logbufcnt += strlen(strname = strdup("n\\a"));
00233
00234 if (i == 0)
00235 sprintf(logbuf, "%s%d(%s)", logbuf, found_uid, strname);
00236 else
00237 sprintf(logbuf, "%s,%d(%s)", logbuf, found_uid, strname);
00238
00239 free(strname);
00240 strname = NULL;
00241 }
00242
00243 strcat(logbuf, ":pgid=");
00244 for (i = 0; i < cntPriGid; i++)
00245 {
00246 gid_t found_gid=-1;
00247
00248 if (set_only_egid)
00249 found_gid = getegid();
00250 else
00251 found_gid = getgid();
00252 grp_info = getgrgid(found_gid);
00253
00254 if (grp_info != NULL)
00255 logbufcnt += strlen (strname = strdup (grp_info->gr_name));
00256 else
00257 logbufcnt += strlen (strname = strdup ("n\\a"));
00258
00259 if (i == 0)
00260 sprintf(logbuf, "%s%d(%s)", logbuf, found_gid, strname);
00261 else
00262 sprintf(logbuf, "%s,%d(%s)", logbuf, found_gid, strname);
00263
00264 free(strname);
00265 strname = NULL;
00266 }
00267
00268 if ((ngroups=getgroups(0, NULL)) > 0)
00269 {
00270 list = (gid_t *) malloc(ngroups * sizeof(gid_t));
00271 if (getgroups(ngroups, list) > 0)
00272 {
00273 strcat(logbuf, ":sgid=");
00274 for (i = 0; i < ngroups; i++)
00275 {
00276 grp_info = getgrgid(list[i]);
00277 strname = (char *) malloc (sizeof(char) * 30);
00278
00279 if (grp_info != NULL)
00280 strname = strdup (grp_info->gr_name);
00281 else
00282 strname = strdup ("n\\a");
00283
00284 if (i == 0)
00285 sprintf(logbuf, "%s%d(%s)", logbuf, (secGid[i]), strname);
00286 else
00287 sprintf(logbuf, "%s,%d(%s)", logbuf, (secGid[i]), strname);
00288
00289 free(strname);
00290 strname = NULL;
00291 grp_info = NULL;
00292 }
00293 }
00294 }
00295
00296 lcmaps_log_time(0, "%s: %s\n", logstr, logbuf);
00297
00298
00299
00300 free(logbuf);
00301 return 0;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 int plugin_initialize(
00319 int argc,
00320 char ** argv
00321 )
00322 {
00323 int i, j;
00324 char * logstr = "\tlcmaps_plugin_posix_enf-plugin_initialize()";
00325
00326
00327 lcmaps_log_debug(1,"%s: passed arguments:\n", logstr);
00328 for (i=0; i < argc; i++)
00329 {
00330 lcmaps_log_debug(2,"%s: arg %d is %s\n", logstr, i, argv[i]);
00331 }
00332
00333
00334
00335
00336 for (i = 1; i < argc; i++)
00337 {
00338
00339 if ( (((strcmp(argv[i], "-maxuid") == 0) ||
00340 (strcmp(argv[i], "-MAXUID") == 0)) &&
00341 (maxuid == MAX_UNDEFINED))
00342 && (i + 1 < argc) )
00343 {
00344 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00345 {
00346 lcmaps_log_debug(2,"%s: Checking if argument behind \"-maxuid\" is a number\n", logstr);
00347 for (j = 0; j < strlen(argv[i + 1]); j++)
00348 {
00349 if (!isdigit((argv[i + 1])[j]))
00350 {
00351 lcmaps_log(0,"%s\tError: maybe found some digits, but there is at least one char corrupting this parameter: %s\n", logstr, argv[i + 1]);
00352 maxuid = -1;
00353 goto fail_posix;
00354 }
00355 }
00356 maxuid = atoi(argv[i + 1]);
00357 }
00358 else
00359 {
00360 lcmaps_log(0,"%s: no argument found for %s (failure)\n", logstr, argv[i]);
00361 goto fail_posix;
00362 }
00363 i++;
00364 }
00365
00366
00367 else if ( (((strcmp(argv[i], "-maxpgid") == 0) ||
00368 (strcmp(argv[i], "-MAXPGID") == 0)) &&
00369 (maxpgid == MAX_UNDEFINED))
00370 && (i + 1 < argc) )
00371 {
00372 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00373 {
00374 lcmaps_log_debug(2,"%s: Checking if argument behind \"-maxpgid\" is a number\n", logstr);
00375 for (j = 0; j < strlen(argv[i + 1]); j++)
00376 {
00377 if (!isdigit((argv[i + 1])[j]))
00378 {
00379 lcmaps_log(0,"%s\tError: maybe found some digits, but there is at least one char corrupting this parameter: %s\n", logstr, argv[i + 1]);
00380 maxpgid = -1;
00381 goto fail_posix;
00382 }
00383 }
00384 maxpgid = atoi(argv[i + 1]);
00385 }
00386 else
00387 {
00388 lcmaps_log(0,"%s: no argument found for %s (failure)\n", logstr, argv[i]);
00389 goto fail_posix;
00390 }
00391 i++;
00392 }
00393
00394
00395 else if ( (((strcmp(argv[i], "-maxsgid") == 0) ||
00396 (strcmp(argv[i], "-MAXSGID") == 0)) &&
00397 (maxsgid == MAX_UNDEFINED))
00398 && (i + 1 < argc) )
00399 {
00400 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00401 {
00402 lcmaps_log_debug(2,"%s: Checking if argument behind \"-maxsgid\" is a number\n", logstr);
00403 for (j = 0; j < strlen(argv[i + 1]); j++)
00404 {
00405 if (!isdigit((argv[i + 1])[j]))
00406 {
00407 lcmaps_log(0,"%s\tError: maybe found some digits, but there is atleast one char corrupting this parameter: %s\n", logstr, argv[i + 1]);
00408 maxsgid = -1;
00409 goto fail_posix;
00410 }
00411 }
00412 maxsgid = atoi(argv[i + 1]);
00413 }
00414 else
00415 {
00416 lcmaps_log(0,"%s: no argument found for %s (failure)\n", logstr, argv[i]);
00417 goto fail_posix;
00418 }
00419 i++;
00420 }
00421 else if ( (strcmp(argv[i], "-set_only_euid") == 0)
00422 && (i + 1 < argc) )
00423 {
00424 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00425 {
00426 if (strcmp(argv[i+1],"yes") == 0)
00427 {
00428 set_only_euid = 1;
00429 }
00430 else if (strcmp(argv[i+1],"no") == 0)
00431 {
00432 set_only_euid = 0;
00433 }
00434 else
00435 {
00436 lcmaps_log(0,"%s: use \"yes\" or \"no\" for option %s\n", logstr, argv[i]);
00437 goto fail_posix;
00438 }
00439 }
00440 else
00441 {
00442 lcmaps_log(0,"%s: no argument found for %s (failure)\n", logstr, argv[i]);
00443 goto fail_posix;
00444 }
00445 i++;
00446 }
00447 else if ( (strcmp(argv[i], "-set_only_egid") == 0)
00448 && (i + 1 < argc) )
00449 {
00450 if ((argv[i + 1] != NULL) && (strlen(argv[i + 1]) > 0))
00451 {
00452 if (strcmp(argv[i+1],"yes") == 0)
00453 {
00454 set_only_egid = 1;
00455 }
00456 else if (strcmp(argv[i+1],"no") == 0)
00457 {
00458 set_only_egid = 0;
00459 }
00460 else
00461 {
00462 lcmaps_log(0,"%s: use \"yes\" or \"no\" for option %s\n", logstr, argv[i]);
00463 goto fail_posix;
00464 }
00465 }
00466 else
00467 {
00468 lcmaps_log(0,"%s: no argument found for %s (failure)\n", logstr, argv[i]);
00469 goto fail_posix;
00470 }
00471 i++;
00472 }
00473 }
00474
00475 if (maxsgid > NGROUPS)
00476 {
00477 lcmaps_log(0,"%s\tError: The prefered set maximum of %d Secondary Gid's exceeds the system maximum of NGROUPS witch is set to %d on this system\n", logstr, maxsgid, NGROUPS);
00478 goto fail_posix;
00479 }
00480 else if (maxsgid == MAX_UNDEFINED)
00481 {
00482 lcmaps_log(0,"%s\tAuto set maximum Secondary Gid's to system maximum of NGROUPS witch is set to %d on this system\n", logstr, NGROUPS);
00483 }
00484
00485
00486 lcmaps_log_debug(2,"%s: Summary init maxuid : %d\n", logstr, maxuid);
00487 lcmaps_log_debug(2,"%s: Summary init maxpgid : %d\n", logstr, maxpgid);
00488 lcmaps_log_debug(2,"%s: Summary init maxsgid : %d\n", logstr, maxsgid);
00489
00490 return LCMAPS_MOD_SUCCESS;
00491
00492
00493 fail_posix:
00494 return LCMAPS_MOD_FAIL;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 int plugin_introspect(
00508 int * argc,
00509 lcmaps_argument_t ** argv
00510 )
00511 {
00512 char * logstr = "\tlcmaps_plugin_posix_enf-plugin_introspect()";
00513
00514 static lcmaps_argument_t argList[] = {
00515 {NULL , NULL , -1, NULL}
00516 };
00517
00518 lcmaps_log_debug(1,"%s: introspecting\n", logstr);
00519
00520 *argv = argList;
00521 *argc = lcmaps_cntArgs(argList);
00522 lcmaps_log_debug(1,"%s: address first argument: 0x%x\n", logstr, argList);
00523
00524 return LCMAPS_MOD_SUCCESS;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 int plugin_run(
00540 int argc,
00541 lcmaps_argument_t * argv
00542 )
00543 {
00544 char * logstr = "\tlcmaps_plugin_posix_enf-plugin_run()";
00545 int i, t;
00546 gid_t * list = NULL;
00547 int ngroups = 0;
00548
00549 char * dn = NULL;
00550 uid_t * uid = NULL;
00551 int cntUid;
00552 gid_t * priGid = NULL;
00553 int cntPriGid;
00554 gid_t * secGid = NULL;
00555 int cntSecGid;
00556 struct passwd * root_info = NULL;
00557
00558
00559
00560
00561 lcmaps_log_debug(1,"%s\n", logstr);
00562
00563 uid = getCredentialData(UID, &cntUid);
00564 priGid = getCredentialData(PRI_GID, &cntPriGid);
00565 secGid = getCredentialData(SEC_GID, &cntSecGid);
00566 lcmaps_log_debug(2,"%s: number of uids: %d, priGids: %d, secGids: %d\n", logstr, cntUid,cntPriGid,cntSecGid);
00567
00568
00569 if (maxuid != MAX_UNDEFINED)
00570 {
00571 lcmaps_log_debug(2,"%s: max number of uids: %d\n", logstr, maxuid);
00572 if (cntUid > maxuid)
00573 {
00574 lcmaps_log(0, "%s:\tError: The set amount of uid's gathered exceeds the maximum of %d uid('s) by %d\n", logstr, maxuid, (cntUid - maxuid));
00575 goto fail_posix;
00576 }
00577 }
00578 if (maxpgid != MAX_UNDEFINED)
00579 {
00580 lcmaps_log_debug(2,"%s: max number of primary gid('s): %d\n", logstr, maxpgid);
00581 if (cntPriGid > maxpgid)
00582 {
00583 lcmaps_log(0, "%s:\tError: The set amount of primary gid's gathered exceeds the maximum of %d primary gid('s) by %d\n", logstr, maxpgid, (cntPriGid - maxpgid));
00584 goto fail_posix;
00585 }
00586 }
00587 if (maxsgid != MAX_UNDEFINED)
00588 {
00589 lcmaps_log_debug(2,"%s: max number of secondary gid's: %d\n", logstr, maxsgid);
00590 if (cntSecGid > maxsgid)
00591 {
00592 lcmaps_log(0, "%s:\tError: The set amount of secondary gid's gathered exceeds the maximum of %d secunadary gid's by %d\n", logstr, maxsgid, (cntSecGid - maxsgid));
00593 goto fail_posix;
00594 }
00595 }
00596
00597
00598
00599 if (getuid() != 0)
00600 {
00601 lcmaps_log(0, "%s: The service did not initialize with Root! -> %d\n", logstr, getuid());
00602 goto fail_posix;
00603 }
00604
00605
00606 if ((root_info=getpwuid(0)) == NULL)
00607 {
00608 lcmaps_log(0, "%s: cannot get passwd info for root\n", logstr);
00609 if (errno==ENOMEM)
00610 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00611 goto fail_posix;
00612 }
00613 lcmaps_log_debug(3,"%s: Name of root: %s\n", logstr, root_info->pw_name);
00614 lcmaps_log_debug(3,"%s: Je real GID was -> %d\n", logstr, getgid());
00615 lcmaps_log_debug(3,"%s: Je effective GID was -> %d\n", logstr, getegid());
00616
00617
00618 if (cntPriGid > 0)
00619 {
00620 if (set_only_egid)
00621 if (setregid(-1, priGid[0]) != 0)
00622 {
00623 lcmaps_log(0, "%s: cannot set effective gid by setregid()\n", logstr);
00624 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00625 }
00626 else
00627 {
00628 lcmaps_log_debug(1,"%s: Setting only effective primary gid to %d\n", logstr, (int) priGid[0]);
00629 }
00630 else
00631 if (setregid(priGid[0], priGid[0]) != 0)
00632 {
00633 lcmaps_log(0, "%s: cannot set real and effective setregid()\n", logstr);
00634 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00635 }
00636 }
00637 else
00638 {
00639 lcmaps_log(0, "%s: No primary group IDs found, need at least 1 !\n", logstr);
00640 goto fail_posix;
00641 }
00642
00643 lcmaps_log_debug(3,"%s: Je real GID is nu -> %d\n", logstr, getgid());
00644 lcmaps_log_debug(3,"%s: Je effective GID is nu -> %d\n", logstr, getegid());
00645
00646
00647 if (initgroups(root_info->pw_name, root_info->pw_gid)!=0)
00648 {
00649 lcmaps_log(0, "%s: error in initgroups() call\n", logstr);
00650 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00651 goto fail_posix;
00652 }
00653
00654
00655 if ((ngroups=getgroups(0, NULL)) < 0)
00656 {
00657 lcmaps_log(0, "%s: error in getgroups() call\n", logstr);
00658 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00659 goto fail_posix;
00660 }
00661 lcmaps_log_debug(3,"%s: found %d sec group IDs initially\n", logstr, ngroups);
00662 list = (gid_t *) malloc(ngroups * sizeof(gid_t));
00663
00664
00665 if (getgroups(ngroups, list) < 0)
00666 {
00667 lcmaps_log(0, "%s: error in getgroups() call\n", logstr);
00668 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00669 goto fail_posix;
00670 }
00671 for (t = 0; t < ngroups; t++)
00672 {
00673 lcmaps_log_debug(3,"%s: Je Sec. Gids waren -> %d\n", logstr, list[t]);
00674 }
00675 if (list) free(list);
00676 list=(gid_t *) NULL;
00677
00678
00679 if (setgroups(cntSecGid, secGid)!=0)
00680 {
00681 switch (errno)
00682 {
00683 case EFAULT :
00684 {
00685 lcmaps_log_debug(1, "%s: Not that fatal but serious error\n", logstr);
00686 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00687 goto fail_posix;
00688 break;
00689 }
00690 case EPERM :
00691 {
00692 lcmaps_log_debug(1, "%s: You are not ROOT\n", logstr);
00693 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00694 goto fail_posix;
00695 break;
00696 }
00697 case EINVAL :
00698 {
00699 for (i = 0; i < cntSecGid; i++)
00700 {
00701 lcmaps_log_debug(1,"%s: > i = %d met %d\n", logstr, i, secGid[i]);
00702 }
00703 lcmaps_log_debug(1, "%s: Invalid GID list\n", logstr);
00704 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00705 goto fail_posix;
00706 break;
00707 }
00708 default :
00709 {
00710 lcmaps_log_debug(1, "%s: Unspecified error in setgroups()\n", logstr);
00711 goto fail_posix;
00712 }
00713 }
00714 }
00715
00716 if ((ngroups=getgroups(0, NULL)) < 0)
00717 {
00718 lcmaps_log(0, "%s: error in getgroups() call\n", logstr);
00719 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00720 goto fail_posix;
00721 }
00722 lcmaps_log_debug(1,"%s: found %d sec gids after setgroups(), cntSecGid=%d\n", logstr, ngroups,cntSecGid);
00723 list = (gid_t *) malloc(ngroups * sizeof(gid_t));
00724
00725
00726 if (getgroups(ngroups, list) < 0)
00727 {
00728 lcmaps_log(0, "%s: error in getgroups() call\n", logstr);
00729 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00730 goto fail_posix;
00731 }
00732 for (t = 0; t < ngroups; t++)
00733 {
00734 lcmaps_log_debug(2,"%s: Je Sec. Gid s zijn nu -> %d\n", logstr, list[t]);
00735 }
00736
00737 lcmaps_log_debug(2,"%s: Je was user -> %d\n", logstr, getuid());
00738
00739
00740 if (cntUid > 0)
00741 {
00742 if (set_only_euid)
00743 if (setreuid(-1, uid[0]) != 0)
00744 {
00745 lcmaps_log(0, "%s: cannot set effective uid by setreuid()\n", logstr);
00746 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00747 }
00748 else
00749 {
00750 lcmaps_log_debug(1,"%s: Setting only effective uid to %d\n", logstr, (int) uid[0]);
00751 }
00752 else
00753 if (setreuid(uid[0], uid[0]) != 0)
00754 {
00755 lcmaps_log(0, "%s: cannot setreuid()\n", logstr);
00756 lcmaps_log(0, "%s: %s\n", logstr, strerror(errno));
00757 }
00758 }
00759 else
00760 {
00761 lcmaps_log(0, "%s: No user IDs found, need at least 1 !\n", logstr);
00762 goto fail_posix;
00763 }
00764
00765 lcmaps_log_debug(2,"%s: Je bent nu geworden -> %d\n", logstr, getuid());
00766 lcmaps_log_debug(1,"%s: Je real UID is -> %d\n", logstr, getuid());
00767 lcmaps_log_debug(1,"%s: Je effective UID is -> %d\n", logstr, geteuid());
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 if ( (!set_only_euid) && ((getuid() == 0) || (geteuid() == 0)) )
00780 {
00781 lcmaps_log(0, "%s: real and or effective uid == 0, which is not allowed at this stage\n", logstr);
00782 goto fail_posix;
00783 }
00784 else if (geteuid() == 0)
00785 {
00786 lcmaps_log(0, "%s: effective uid == 0, which is not allowed at this stage\n", logstr);
00787 goto fail_posix;
00788 }
00789
00790 if ( (!set_only_egid) && ((getgid() == 0) || (getegid() == 0)) )
00791 {
00792 lcmaps_log(0, "%s: real and or effective gid == 0, which is not allowed at this stage\n", logstr);
00793 goto fail_posix;
00794 }
00795 else if (getegid() == 0)
00796 {
00797 lcmaps_log(0, "%s: effective gid == 0, which is not allowed at this stage\n", logstr);
00798 goto fail_posix;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808 log_cred(dn, uid, cntUid, priGid, cntPriGid, secGid, cntSecGid);
00809
00810
00811
00812 success_posix:
00813 if (list) free(list);
00814 lcmaps_log_time(0,"%s: posix_enf plugin succeeded\n", logstr);
00815 return LCMAPS_MOD_SUCCESS;
00816
00817 fail_posix:
00818 if (list) free(list);
00819 lcmaps_log_time(0,"%s: posix_enf plugin failed\n", logstr);
00820 return LCMAPS_MOD_FAIL;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 int plugin_terminate()
00834 {
00835 char * logstr = "\tlcmaps_plugin_posix_enf-plugin_introspect()";
00836
00837 lcmaps_log_debug(1,"%s: terminating\n", logstr);
00838
00839 return LCMAPS_MOD_SUCCESS;
00840 }
00841
00842
00843
00844
00845
00846
00847
00848