/* * user.c: Part of GNU CSSC. * * * Copyright (C) 1997, Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * * Program for getting the user's login name. */ #ifdef HAVE_UNISTD_H #include #endif #include #include #ifdef STDC_HEADERS #include #include #endif const char usage_str[] = "usage: \"user name\" or \"user group\"\n"; static int duplicate_group(gid_t g, const gid_t *vec, int len) { while (len--) { if (*vec == g) return 1; } return 0; } /* do_groups * * Emits a list of groups associated with the current * process. The effectve group ID is also returned, * and this may be a suplicate entry. */ static gid_t *get_group_list(int *ngroups) { int len; gid_t *grouplist; len = getgroups(0, NULL); if (len < 0) { perror("getgroups"); return NULL; } else { grouplist = malloc((1+len) * sizeof(*grouplist)); if (grouplist) { /* We don't know if the effectve group ID is in * the list returned by grouplist, so find out * and return a list with it included, but only once */ gid_t egid = getegid(); if (getgroups(len, &grouplist[1])) { if (duplicate_group(egid, grouplist+1, len)) { *ngroups = len; return &grouplist[1]; } else { grouplist[0] = egid; *ngroups = len+1; return &grouplist[0]; } } else { perror("getgroups"); return NULL; } } else { perror("malloc"); return NULL; } } } static void do_groups() { int ngroups, i, duplicates; gid_t *list = get_group_list(&ngroups); if (list) { for (i=0; i *p2) return 1; else return 0; } /* Find and print the Id of a group of which we are not a member. * This group will (most likely) not have a name */ static gid_t foreign_group(void) { int ngroups, i, duplicates; gid_t *list = get_group_list(&ngroups); qsort(list, ngroups, sizeof(*list), compare_groups); for (i=1; i 0) return 0; else return 1+list[ngroups-1]; } else /* not a member of any groups? */ { gid_t last_resort = getegid(); if (last_resort > 0) return 0; else return 1+last_resort; } } int main(int argc, char *argv[]) { if (2 == argc) { if (0 == strcmp(argv[1], "name")) { struct passwd *p; const char *pn = "unknown"; p = getpwuid(getuid()); if (p) pn = p->pw_name; fprintf(stdout, "%s\n", pn); return 0; } else if (0 == strcmp(argv[1], "groups")) { do_groups(); return 0; } else if (0 == strcmp(argv[1], "foreigngroup")) { fprintf(stdout, "%ld\n", (long)foreign_group()); return 0; } else if (0 == strcmp(argv[1], "group")) { fprintf(stdout, "%ld\n", (long)getgid()); return 0; } else { fprintf(stderr, "%s", usage_str); return 1; } } else { fprintf(stderr, "%s", usage_str); return 1; } }