int main(int argc, char *argv[]) { struct fstab *fs; struct passwd *pw; struct group *gr; struct quotafile *qfu, *qfg; int i, argnum, maxrun, errs, ch; long done = 0; char *name; errs = maxrun = 0; while ((ch = getopt(argc, argv, "ac:guvl:")) != -1) { switch(ch) { case 'a': aflag++; break; case 'c': if (cflag) usage(); cflag = atoi(optarg); break; case 'g': gflag++; break; case 'u': uflag++; break; case 'v': vflag++; break; case 'l': maxrun = atoi(optarg); break; default: usage(); } } argc -= optind; argv += optind; if ((argc == 0 && !aflag) || (argc > 0 && aflag)) usage(); if (cflag && cflag != 32 && cflag != 64) usage(); if (!gflag && !uflag) { gflag++; uflag++; } if (gflag) { setgrent(); while ((gr = getgrent()) != NULL) (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name, NULL); endgrent(); } if (uflag) { setpwent(); while ((pw = getpwent()) != NULL) (void) addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name, NULL); endpwent(); } /* * The maxrun (-l) option is now deprecated. */ if (maxrun > 0) warnx("the -l option is now deprecated"); if (aflag) exit(checkfstab(uflag, gflag)); if (setfsent() == 0) errx(1, "%s: can't open", FSTAB); while ((fs = getfsent()) != NULL) { if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) && (name = blockcheck(fs->fs_spec))) { done |= 1 << argnum; qfu = NULL; if (uflag) qfu = quota_open(fs, USRQUOTA, O_CREAT|O_RDWR); qfg = NULL; if (gflag) qfg = quota_open(fs, GRPQUOTA, O_CREAT|O_RDWR); if (qfu == NULL && qfg == NULL) continue; errs += chkquota(name, qfu, qfg); if (qfu) quota_close(qfu); if (qfg) quota_close(qfg); } } endfsent(); for (i = 0; i < argc; i++) if ((done & (1 << i)) == 0) fprintf(stderr, "%s not found in %s\n", argv[i], FSTAB); exit(errs); }
static DWORD UmnSrvUpdateAccountInfo( long long Now ) { DWORD dwError = 0; HANDLE hLsass = NULL; HANDLE hReg = NULL; HKEY hParameters = NULL; BOOLEAN bLocalDBOpen = FALSE; // Do not free PSTR pDisableLsassEnum = NULL; DWORD lastUpdated = 0; DWORD lastUpdatedLen = sizeof(lastUpdated); PLW_EVENTLOG_CONNECTION pConn = NULL; dwError = LwEvtOpenEventlog( NULL, &pConn); BAIL_ON_UMN_ERROR(dwError); dwError = LsaOpenServer(&hLsass); BAIL_ON_UMN_ERROR(dwError); dwError = RegOpenServer(&hReg); BAIL_ON_UMN_ERROR(dwError); dwError = RegOpenKeyExA( hReg, NULL, HKEY_THIS_MACHINE "\\Services\\" SERVICE_NAME "\\Parameters", 0, KEY_ALL_ACCESS, &hParameters); BAIL_ON_UMN_ERROR(dwError); dwError = RegGetValueA( hReg, hParameters, NULL, "LastUpdated", 0, NULL, (PBYTE)&lastUpdated, &lastUpdatedLen); if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE) { lastUpdated = 0; dwError = 0; } BAIL_ON_UMN_ERROR(dwError); /* processing local users/groups so disable AD user/group enumeration */ pDisableLsassEnum = getenv("_DISABLE_LSASS_NSS_ENUMERATION"); if (!pDisableLsassEnum || strcmp(pDisableLsassEnum, "1")) { /* Note, this code must leak memory. * * Putenv uses the memory passed to it, that it is it does not copy the * string. There is no Unix standard to unset an environment variable, * and the string passed to putenv must be accessible as long as the * program is running. A static string cannot be used because the * container could out live this service. There is no opportunity to * free the string before the program ends, because the variable must * be accessible for the duration of the program. */ dwError = LwAllocateString( "_DISABLE_LSASS_NSS_ENUMERATION=1", &pDisableLsassEnum); BAIL_ON_UMN_ERROR(dwError); putenv(pDisableLsassEnum); } setpwent(); setgrent(); bLocalDBOpen = TRUE; dwError = UmnSrvUpdateUsers( hLsass, pConn, hReg, hParameters, lastUpdated, Now); BAIL_ON_UMN_ERROR(dwError); dwError = UmnSrvUpdateGroups( hLsass, pConn, hReg, hParameters, lastUpdated, Now); BAIL_ON_UMN_ERROR(dwError); endpwent(); endgrent(); bLocalDBOpen = FALSE; dwError = UmnSrvUpdateADAccounts( hLsass, pConn, hReg, hParameters, lastUpdated, Now); BAIL_ON_UMN_ERROR(dwError); lastUpdated = Now; dwError = RegSetValueExA( hReg, hParameters, "LastUpdated", 0, REG_DWORD, (PBYTE)&lastUpdated, sizeof(lastUpdated)); BAIL_ON_UMN_ERROR(dwError); cleanup: if (bLocalDBOpen) { endpwent(); endgrent(); } if (hLsass) { LsaCloseServer(hLsass); } if (hReg) { RegCloseServer(hReg); } if (pConn) { LwEvtCloseEventlog(pConn); } return dwError; error: goto cleanup; }
static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP { char *host, *user, *domain; setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum, NULL, 0) && password_ok(user,password)) { endnetgrent(); return(user); } } } endnetgrent(); } #endif #ifdef HAVE_GETGRENT { struct group *gptr; setgrent(); while ((gptr = (struct group *)getgrent())) { if (strequal(gptr->gr_name,group)) break; } /* * As user_ok can recurse doing a getgrent(), we must * copy the member list into a pstring on the stack before * use. Bug pointed out by [email protected]. */ if (gptr) { pstring member_list; char *member; size_t copied_len = 0; int i; *member_list = '\0'; member = member_list; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { size_t member_len = strlen(gptr->gr_mem[i]) + 1; if( copied_len + member_len < sizeof(pstring)) { DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i])); safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1); copied_len += member_len; member += copied_len; } else { *member = '\0'; } } endgrent(); member = member_list; while (*member) { static fstring name; fstrcpy(name,member); if (user_ok(name,snum, NULL, 0) && password_ok(name,password)) { endgrent(); return(&name[0]); } DEBUG(10,("validate_group = member = %s\n", member)); member += strlen(member) + 1; } } else { endgrent(); return NULL; } } #endif return(NULL); }
/* * Set the current user to 'identifier'. 'cacheid', if non-null, * points to a 16-byte binary key to cache identifier's information * with. */ static struct auth_state *mynewstate(const char *identifier) { struct auth_state *newstate; struct passwd *pwd; struct group *grp; #if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__) gid_t gid, *groupids = NULL; int ret, ngroups = 10, oldngroups; #else char **mem; #endif identifier = mycanonifyid(identifier, 0); if (!identifier) return 0; if (!strncmp(identifier, "group:", 6)) return 0; newstate = (struct auth_state *)xmalloc(sizeof(struct auth_state)); strcpy(newstate->userid, identifier); strarray_init(&newstate->groups); if(!libcyrus_config_getswitch(CYRUSOPT_AUTH_UNIX_GROUP_ENABLE)) return newstate; pwd = getpwnam(identifier); #if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__) gid = pwd ? pwd->pw_gid : (gid_t) -1; /* get the group ids */ do { groupids = (gid_t *)xrealloc((gid_t *)groupids, ngroups * sizeof(gid_t)); oldngroups = ngroups; /* copy of ngroups for comparision */ ret = getgrouplist(identifier, gid, groupids, &ngroups); /* * This is tricky. We do this as long as getgrouplist tells us to * realloc _and_ the number of groups changes. It tells us to realloc * also in the case of failure... */ } while (ret == -1 && ngroups != oldngroups); if (ret == -1) goto err; while (ngroups--) { if (pwd || groupids[ngroups] != gid) { if ((grp = getgrgid(groupids[ngroups]))) strarray_append(&newstate->groups, grp->gr_name); } } err: if (groupids) free(groupids); #else /* !HAVE_GETGROUPLIST */ setgrent(); while ((grp = getgrent())) { for (mem = grp->gr_mem; *mem; mem++) { if (!strcmp(*mem, identifier)) break; } if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) strarray_append(&newstate->groups, grp->gr_name); } endgrent(); #endif /* HAVE_GETGROUPLIST */ return newstate; }
static void do_enter_key (WDialog * h, int f_pos) { WListbox *chl_list; struct passwd *chl_pass; struct group *chl_grp; int fe; gboolean chl_end, is_owner; do { int result; WDialog *chl_dlg; const char *title; int lxx, lyy, b_pos; is_owner = (f_pos == 3); title = is_owner ? _("owner") : _("group"); lxx = (COLS - 74) / 2 + (is_owner ? 35 : 53); lyy = (LINES - 13) / 2; chl_end = FALSE; chl_dlg = dlg_create (TRUE, lyy, lxx, 13, 17, dialog_colors, chl_callback, NULL, "[Advanced Chown]", title, DLG_COMPACT); /* get new listboxes */ chl_list = listbox_new (1, 1, 11, 15, FALSE, NULL); listbox_add_item (chl_list, LISTBOX_APPEND_AT_END, 0, "<Unknown>", NULL, FALSE); if (is_owner) { /* get and put user names in the listbox */ setpwent (); while ((chl_pass = getpwent ()) != NULL) listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_pass->pw_name, NULL, FALSE); endpwent (); fe = listbox_search_text (chl_list, get_owner (sf_stat->st_uid)); } else { /* get and put group names in the listbox */ setgrent (); while ((chl_grp = getgrent ()) != NULL) listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_grp->gr_name, NULL, FALSE); endgrent (); fe = listbox_search_text (chl_list, get_group (sf_stat->st_gid)); } listbox_select_entry (chl_list, fe); b_pos = chl_list->pos; add_widget (chl_dlg, chl_list); result = dlg_run (chl_dlg); if (result != B_CANCEL) { if (b_pos != chl_list->pos) { gboolean ok = FALSE; char *text; listbox_get_current (chl_list, &text, NULL); if (is_owner) { chl_pass = getpwnam (text); if (chl_pass != NULL) { ok = TRUE; sf_stat->st_uid = chl_pass->pw_uid; } } else { chl_grp = getgrnam (text); if (chl_grp != NULL) { sf_stat->st_gid = chl_grp->gr_gid; ok = TRUE; } } if (ok) { ch_flags[f_pos + 6] = '+'; update_ownership (); } dlg_focus (h); if (ok) print_flags (); } if (result == KEY_LEFT) { if (!is_owner) chl_end = TRUE; dlg_one_up (ch_dlg); f_pos--; } else if (result == KEY_RIGHT) { if (is_owner) chl_end = TRUE; dlg_one_down (ch_dlg); f_pos++; } } /* Here we used to redraw the window */ dlg_destroy (chl_dlg); } while (chl_end); }
static void do_enter_key (Dlg_head * h, int f_pos) { Dlg_head *chl_dlg; WListbox *chl_list; struct passwd *chl_pass; struct group *chl_grp; WLEntry *fe; int lxx, lyy, chl_end, b_pos; int is_owner; const char *title; do { is_owner = (f_pos == 3); title = is_owner ? _("owner") : _("group"); lxx = (COLS - 74) / 2 + (is_owner ? 35 : 53); lyy = (LINES - 13) / 2; chl_end = 0; chl_dlg = create_dlg (lyy, lxx, 13, 17, dialog_colors, chl_callback, "[Advanced Chown]", title, DLG_COMPACT | DLG_REVERSE); /* get new listboxes */ chl_list = listbox_new (1, 1, 11, 15, NULL); listbox_add_item (chl_list, LISTBOX_APPEND_AT_END, 0, "<Unknown>", NULL); if (is_owner) { /* get and put user names in the listbox */ setpwent (); while ((chl_pass = getpwent ())) { listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_pass->pw_name, NULL); } endpwent (); fe = listbox_search_text (chl_list, get_owner (sf_stat->st_uid)); } else { /* get and put group names in the listbox */ setgrent (); while ((chl_grp = getgrent ())) { listbox_add_item (chl_list, LISTBOX_APPEND_SORTED, 0, chl_grp->gr_name, NULL); } endgrent (); fe = listbox_search_text (chl_list, get_group (sf_stat->st_gid)); } if (fe) listbox_select_entry (chl_list, fe); b_pos = chl_list->pos; add_widget (chl_dlg, chl_list); run_dlg (chl_dlg); if (b_pos != chl_list->pos) { int ok = 0; if (is_owner) { chl_pass = getpwnam (chl_list->current->text); if (chl_pass) { ok = 1; sf_stat->st_uid = chl_pass->pw_uid; } } else { chl_grp = getgrnam (chl_list->current->text); if (chl_grp) { sf_stat->st_gid = chl_grp->gr_gid; ok = 1; } } if (ok) { ch_flags[f_pos + 6] = '+'; update_ownership (); } dlg_focus (h); if (ok) print_flags (); } if (chl_dlg->ret_value == KEY_LEFT) { if (!is_owner) chl_end = 1; dlg_one_up (ch_dlg); f_pos--; } else if (chl_dlg->ret_value == KEY_RIGHT) { if (is_owner) chl_end = 1; dlg_one_down (ch_dlg); f_pos++; } /* Here we used to redraw the window */ destroy_dlg (chl_dlg); } while (chl_end); }
int new_syslogininfo(/*out*/syslogin_info_t** info, sys_userid_t uid) { int err; memblock_t mblock = memblock_FREE; slock_mutex(&s_syslogininfo_lock); errno = 0; struct passwd* pwd = getpwuid(uid); if (!pwd) { if (errno) { err = errno; TRACESYSCALL_ERRLOG("getpwuid(uid)", err); PRINTUINT32_ERRLOG(uid); } else { err = ENOENT; } goto UNLOCK; } size_t namesize = strlen(pwd->pw_name) + 1; // size username size_t nrofgrp = 0; #define GELEMSIZE (sizeof(sys_groupid_t) + sizeof(char*)) setgrent(); for (;;) { errno = 0; struct group* grp = getgrent(); if (!grp) { if (errno) { err = errno; TRACESYSCALL_ERRLOG("getgrent", err); goto UNLOCK; } break; } bool ismatch = (grp->gr_gid == pwd->pw_gid); for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) { ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name)); } if (ismatch) { size_t len = strlen(grp->gr_name); if (nrofgrp == (SIZE_MAX/GELEMSIZE) || namesize >= SIZE_MAX/2 || len >= SIZE_MAX/2) { err = ENOMEM; goto UNLOCK; } nrofgrp ++; namesize += len + 1; } } size_t size = sizeof(syslogin_info_t) + namesize; size_t arrsize = nrofgrp * GELEMSIZE; if (size <= namesize) size = 0; size += arrsize; if (size <= arrsize) { err = ENOMEM; goto UNLOCK; } err = ALLOC_MM(size, &mblock); if (err) goto UNLOCK; syslogin_info_t* newobj = (syslogin_info_t*) mblock.addr; uint8_t* data = mblock.addr + sizeof(syslogin_info_t); size_t datasize = size - sizeof(syslogin_info_t); size_t dataoff; newobj->size = size; newobj->uid = uid; newobj->nrgroups = nrofgrp; newobj->gmain = 0; newobj->gname = (const char**) data; dataoff = nrofgrp * sizeof(char*); newobj->gid = (sys_groupid_t*) (data + dataoff); dataoff += nrofgrp * sizeof(sys_groupid_t); size_t fieldsize = strlen(pwd->pw_name) + 1; if (fieldsize > (datasize - dataoff)) { err = EAGAIN; goto UNLOCK; } memcpy(data + dataoff, pwd->pw_name, fieldsize); newobj->uname = (char*) (data + dataoff); dataoff += fieldsize; setgrent(); for (size_t gi = 0; gi < nrofgrp; ) { errno = 0; struct group* grp = getgrent(); if (!grp) { err = errno ? errno : ENOENT; TRACESYSCALL_ERRLOG("getgrent", err); goto UNLOCK; } bool ismatch = (grp->gr_gid == pwd->pw_gid); for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) { ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name)); } if (ismatch) { fieldsize = strlen(grp->gr_name) + 1; if (fieldsize > (datasize - dataoff)) { err = EAGAIN; goto UNLOCK; } char* gname = (char*) (data + dataoff); dataoff += fieldsize; memcpy(gname, grp->gr_name, fieldsize); if (grp->gr_gid == pwd->pw_gid) { newobj->gmain = gi; } newobj->gid[gi] = grp->gr_gid; newobj->gname[gi] = gname; ++gi; } } *info = newobj; UNLOCK: endgrent(); endpwent(); sunlock_mutex(&s_syslogininfo_lock); if (err) goto ONERR; return 0; ONERR: FREE_MM(&mblock); if (ENOENT != err) { TRACEEXIT_ERRLOG(err); } return err; }
static Dlg_head * init_chown (void) { int i; struct passwd *l_pass; struct group *l_grp; Dlg_head *ch_dlg; do_refresh (); end_chown = need_update = current_file = 0; single_set = (current_panel->marked < 2) ? 3 : 0; ch_dlg = create_dlg (TRUE, 0, 0, 18, 74, dialog_colors, chown_callback, "[Chown]", _("Chown command"), DLG_CENTER | DLG_REVERSE); for (i = 0; i < BUTTONS - single_set; i++) add_widget (ch_dlg, button_new (BY + chown_but[i].y, BX + chown_but[i].x, chown_but[i].ret_cmd, chown_but[i].flags, _(chown_but[i].text), 0)); /* Add the widgets for the file information */ for (i = 0; i < LABELS; i++) { chown_label[i].l = label_new (chown_label[i].y, chown_label[i].x, ""); add_widget (ch_dlg, chown_label[i].l); } /* get new listboxes */ l_user = listbox_new (UY + 1, UX + 1, 10, 19, FALSE, NULL); l_group = listbox_new (GY + 1, GX + 1, 10, 19, FALSE, NULL); /* add fields for unknown names (numbers) */ listbox_add_item (l_user, LISTBOX_APPEND_AT_END, 0, _("<Unknown user>"), NULL); listbox_add_item (l_group, LISTBOX_APPEND_AT_END, 0, _("<Unknown group>"), NULL); /* get and put user names in the listbox */ setpwent (); while ((l_pass = getpwent ()) != NULL) { listbox_add_item (l_user, LISTBOX_APPEND_SORTED, 0, l_pass->pw_name, NULL); } endpwent (); /* get and put group names in the listbox */ setgrent (); while ((l_grp = getgrent ()) != NULL) { listbox_add_item (l_group, LISTBOX_APPEND_SORTED, 0, l_grp->gr_name, NULL); } endgrent (); add_widget (ch_dlg, groupbox_new (TY, TX, 12, 19, _("File"))); /* add listboxes to the dialogs */ add_widget (ch_dlg, l_group); add_widget (ch_dlg, groupbox_new (GY, GX, 12, 21, _("Group name"))); add_widget (ch_dlg, l_user); add_widget (ch_dlg, groupbox_new (UY, UX, 12, 21, _("User name"))); return ch_dlg; }
int main(int argc, char **argv) { struct fstab *fs; struct passwd *pw; struct group *gr; struct quotaname *auxdata; int i, argnum, maxrun, errs; long done = 0; char ch, *name; errs = maxrun = 0; while ((ch = getopt(argc, argv, "aguvl:")) != -1) { switch(ch) { case 'a': aflag++; break; case 'g': gflag++; break; case 'u': uflag++; break; case 'v': vflag++; break; case 'l': maxrun = atoi(optarg); break; default: usage(); } } argc -= optind; argv += optind; if ((argc == 0 && !aflag) || (argc > 0 && aflag)) usage(); if (!gflag && !uflag) { gflag++; uflag++; } if (gflag) { setgrent(); while ((gr = getgrent()) != NULL) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name); endgrent(); } if (uflag) { setpwent(); while ((pw = getpwent()) != NULL) addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name); endpwent(); } if (aflag) exit(checkfstab(1, maxrun, needchk, chkquota)); if (setfsent() == 0) errx(1, "%s: can't open", FSTAB); while ((fs = getfsent()) != NULL) { if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) && (auxdata = needchk(fs)) && (name = blockcheck(fs->fs_spec))) { done |= 1 << argnum; errs += chkquota(name, fs->fs_file, auxdata); } } endfsent(); for (i = 0; i < argc; i++) if ((done & (1 << i)) == 0) fprintf(stderr, "%s not found in %s\n", argv[i], FSTAB); exit(errs); }
int main(int argc, char *argv[]) { struct fstab *fs; struct passwd *pw; struct group *gr; struct quotaname *auxdata; int i, argnum, maxrun, errs, ch; u_int64_t done = 0; /* XXX supports maximum 64 filesystems */ char *name; errs = maxrun = 0; while ((ch = getopt(argc, argv, "adguvl:")) != -1) { switch(ch) { case 'a': flags |= CHECK_PREEN; break; case 'd': flags |= CHECK_DEBUG; break; case 'g': gflag++; break; case 'l': maxrun = atoi(optarg); break; case 'u': uflag++; break; case 'v': flags |= CHECK_VERBOSE; break; default: usage(); } } argc -= optind; argv += optind; if ((argc == 0 && !(flags&CHECK_PREEN)) || (argc > 0 && (flags&CHECK_PREEN))) usage(); if (!gflag && !uflag) { gflag++; uflag++; } if (gflag) { setgrent(); while ((gr = getgrent()) != 0) (void) addid(gr->gr_gid, GRPQUOTA, gr->gr_name); endgrent(); } if (uflag) { setpwent(); while ((pw = getpwent()) != 0) (void) addid(pw->pw_uid, USRQUOTA, pw->pw_name); endpwent(); } if (flags&CHECK_PREEN) exit(checkfstab(flags, maxrun, needchk, chkquota)); if (setfsent() == 0) err(1, "%s: can't open", FSTAB); while ((fs = getfsent()) != NULL) { if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) && (auxdata = needchk(fs)) && (name = blockcheck(fs->fs_spec))) { done |= 1 << argnum; errs += chkquota(fs->fs_vfstype, name, fs->fs_file, auxdata, NULL); } } endfsent(); for (i = 0; i < argc; i++) if ((done & (1 << i)) == 0) fprintf(stderr, "%s not found in %s\n", argv[i], FSTAB); exit(errs); }
static int get_grall (pwd_drv_t *drv) { size_t grp_count = 0; size_t result_count = 0; struct group * grp = NULL; setgrent (); while ((grp = getgrent ())) { grp_count++; result_count += group_term_count( group_mem_length(grp) ); } endgrent (); grp = NULL; ErlDrvTermData *result = (ErlDrvTermData *) driver_alloc (sizeof (ErlDrvTermData) * (result_count + 3)); if (!result) { fprintf (drv->log, "Couldn't allocate memory for result\n"); fflush (drv->log); return send_error (drv, "error", "Couldn't allocate memory for result"); } char **names = (char **) driver_alloc (sizeof (char *) * grp_count); char **pwds = (char **) driver_alloc (sizeof (char *) * grp_count); char ***mems = (char ***) driver_alloc (sizeof (char**) * grp_count); setgrent(); size_t result_idx = 0; ErlDrvTermData *result_it = result; grp = getgrent(); while (grp) { result_it += fill_group (result_it, grp, &names[result_idx], &pwds[result_idx], &mems[result_idx]); result_idx++; grp = getgrent(); } endgrent(); *result_it++ = ERL_DRV_NIL; *result_it++ = ERL_DRV_LIST; *result_it++ = grp_count + 1; int r = send_wrapped (driver_mk_port(drv->port), result, result_count + 3); size_t i; for (i = 0; i < grp_count; ++i) { driver_free (pwds[i]); driver_free (names[i]); char ** mem_it = mems[i]; while (*mem_it) { driver_free (*mem_it); mem_it++; } } driver_free (pwds); driver_free (names); driver_free (mems); driver_free (result); return r; }
int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) { int i, ngroups = 0, ret = 0, maxgroups = *grpcnt, bail; int needyp = 0, foundyp = 0; int *skipyp = &foundyp; extern struct group *_getgrent_yp(int *); struct group *grp; /* * install primary group */ if (ngroups >= maxgroups) { *grpcnt = ngroups; return (-1); } groups[ngroups++] = agroup; /* * Scan the group file to find additional groups. */ setgrent(); while ((grp = _getgrent_yp(skipyp)) || foundyp) { if (foundyp) { if (foundyp > 0) needyp = 1; else skipyp = NULL; foundyp = 0; continue; } if (grp->gr_gid == agroup) continue; for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) if (groups[i] == grp->gr_gid) bail = 1; if (bail) continue; for (i = 0; grp->gr_mem[i]; i++) { if (!strcmp(grp->gr_mem[i], uname)) { if (ngroups >= maxgroups) { ret = -1; goto out; } groups[ngroups++] = grp->gr_gid; break; } } } #ifdef YP /* * If we were told that there is a YP marker, look at netid data. */ if (skipyp && needyp) { char buf[MAXLINELENGTH], *ypdata = NULL, *key; static char *__ypdomain; struct passwd pwstore; int ypdatalen; /* Construct the netid key to look up. */ if (getpwnam_r(uname, &pwstore, buf, sizeof buf, NULL) || (!__ypdomain && yp_get_default_domain(&__ypdomain))) goto out; asprintf(&key, "unix.%u@%s", pwstore.pw_uid, __ypdomain); if (key == NULL) goto out; /* First scan the static netid file. */ switch (_read_netid(key, pwstore.pw_uid, groups, &ngroups, maxgroups)) { case -1: ret = -1; /* FALLTHROUGH */ case 1: free(key); goto out; default: break; } /* Only access YP when there is no static entry. */ if (!yp_bind(__ypdomain) && !yp_match(__ypdomain, "netid.byname", key, (int)strlen(key), &ypdata, &ypdatalen)) if (_parse_netid(ypdata, pwstore.pw_uid, groups, &ngroups, maxgroups) == -1) ret = -1; free(key); free(ypdata); } #endif /* YP */ out: endgrent(); *grpcnt = ngroups; return (ret); }
int main(int argc, char *argv[]) { int i, j; int error, fnd_dup, len, mustfreeai = 0, start_uidpos; struct nfsd_idargs nid; struct passwd *pwd; struct group *grp; int sock, one = 1; SVCXPRT *udptransp; u_short portnum; sigset_t signew; char hostname[MAXHOSTNAMELEN + 1], *cp; struct addrinfo *aip, hints; static uid_t check_dups[MAXUSERMAX]; if (modfind("nfscommon") < 0) { /* Not present in kernel, try loading it */ if (kldload("nfscommon") < 0 || modfind("nfscommon") < 0) errx(1, "Experimental nfs subsystem is not available"); } /* * First, figure out what our domain name and Kerberos Realm * seem to be. Command line args may override these later. */ if (gethostname(hostname, MAXHOSTNAMELEN) == 0) { if ((cp = strchr(hostname, '.')) != NULL && *(cp + 1) != '\0') { dnsname = cp + 1; } else { memset((void *)&hints, 0, sizeof (hints)); hints.ai_flags = AI_CANONNAME; error = getaddrinfo(hostname, NULL, &hints, &aip); if (error == 0) { if (aip->ai_canonname != NULL && (cp = strchr(aip->ai_canonname, '.')) != NULL && *(cp + 1) != '\0') { dnsname = cp + 1; mustfreeai = 1; } else { freeaddrinfo(aip); } } } } nid.nid_usermax = DEFUSERMAX; nid.nid_usertimeout = defusertimeout; argc--; argv++; while (argc >= 1) { if (!strcmp(*argv, "-domain")) { if (argc == 1) usage(); argc--; argv++; strncpy(hostname, *argv, MAXHOSTNAMELEN); hostname[MAXHOSTNAMELEN] = '\0'; dnsname = hostname; } else if (!strcmp(*argv, "-verbose")) { verbose = 1; } else if (!strcmp(*argv, "-force")) { forcestart = 1; } else if (!strcmp(*argv, "-usermax")) { if (argc == 1) usage(); argc--; argv++; i = atoi(*argv); if (i < MINUSERMAX || i > MAXUSERMAX) { fprintf(stderr, "usermax %d out of range %d<->%d\n", i, MINUSERMAX, MAXUSERMAX); usage(); } nid.nid_usermax = i; } else if (!strcmp(*argv, "-usertimeout")) { if (argc == 1) usage(); argc--; argv++; i = atoi(*argv); if (i < 0 || i > 100000) { fprintf(stderr, "usertimeout %d out of range 0<->100000\n", i); usage(); } nid.nid_usertimeout = defusertimeout = i * 60; } else if (nfsuserdcnt == -1) { nfsuserdcnt = atoi(*argv); if (nfsuserdcnt < 1) usage(); if (nfsuserdcnt > MAXNFSUSERD) { warnx("nfsuserd count %d; reset to %d", nfsuserdcnt, DEFNFSUSERD); nfsuserdcnt = DEFNFSUSERD; } } else { usage(); } argc--; argv++; } if (nfsuserdcnt < 1) nfsuserdcnt = DEFNFSUSERD; /* * Strip off leading and trailing '.'s in domain name and map * alphabetics to lower case. */ while (*dnsname == '.') dnsname++; if (*dnsname == '\0') errx(1, "Domain name all '.'"); len = strlen(dnsname); cp = dnsname + len - 1; while (*cp == '.') { *cp = '\0'; len--; cp--; } for (i = 0; i < len; i++) { if (!isascii(dnsname[i])) errx(1, "Domain name has non-ascii char"); if (isupper(dnsname[i])) dnsname[i] = tolower(dnsname[i]); } /* * If the nfsuserd died off ungracefully, this is necessary to * get them to start again. */ if (forcestart && nfssvc(NFSSVC_NFSUSERDDELPORT, NULL) < 0) errx(1, "Can't do nfssvc() to delete the port"); if (verbose) fprintf(stderr, "nfsuserd: domain=%s usermax=%d usertimeout=%d\n", dnsname, nid.nid_usermax, nid.nid_usertimeout); for (i = 0; i < nfsuserdcnt; i++) slaves[i] = (pid_t)-1; /* * Set up the service port to accept requests via UDP from * localhost (127.0.0.1). */ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) err(1, "cannot create udp socket"); /* * Not sure what this does, so I'll leave it here for now. */ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if ((udptransp = svcudp_create(sock)) == NULL) err(1, "Can't set up socket"); /* * By not specifying a protocol, it is linked into the * dispatch queue, but not registered with portmapper, * which is just what I want. */ if (!svc_register(udptransp, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, nfsuserdsrv, 0)) err(1, "Can't register nfsuserd"); /* * Tell the kernel what my port# is. */ portnum = htons(udptransp->xp_port); #ifdef DEBUG printf("portnum=0x%x\n", portnum); #else if (nfssvc(NFSSVC_NFSUSERDPORT, (caddr_t)&portnum) < 0) { if (errno == EPERM) { fprintf(stderr, "Can't start nfsuserd when already running"); fprintf(stderr, " If not running, use the -force option.\n"); } else { fprintf(stderr, "Can't do nfssvc() to add port\n"); } exit(1); } #endif pwd = getpwnam(defaultuser); if (pwd) nid.nid_uid = pwd->pw_uid; else nid.nid_uid = defaultuid; grp = getgrnam(defaultgroup); if (grp) nid.nid_gid = grp->gr_gid; else nid.nid_gid = defaultgid; nid.nid_name = dnsname; nid.nid_namelen = strlen(nid.nid_name); nid.nid_flag = NFSID_INITIALIZE; #ifdef DEBUG printf("Initialize uid=%d gid=%d dns=%s\n", nid.nid_uid, nid.nid_gid, nid.nid_name); #else error = nfssvc(NFSSVC_IDNAME, &nid); if (error) errx(1, "Can't initialize nfs user/groups"); #endif i = 0; /* * Loop around adding all groups. */ setgrent(); while (i < nid.nid_usermax && (grp = getgrent())) { nid.nid_gid = grp->gr_gid; nid.nid_name = grp->gr_name; nid.nid_namelen = strlen(grp->gr_name); nid.nid_flag = NFSID_ADDGID; #ifdef DEBUG printf("add gid=%d name=%s\n", nid.nid_gid, nid.nid_name); #else error = nfssvc(NFSSVC_IDNAME, &nid); if (error) errx(1, "Can't add group %s", grp->gr_name); #endif i++; } /* * Loop around adding all users. */ start_uidpos = i; setpwent(); while (i < nid.nid_usermax && (pwd = getpwent())) { fnd_dup = 0; /* * Yes, this is inefficient, but it is only done once when * the daemon is started and will run in a fraction of a second * for nid_usermax at 10000. If nid_usermax is cranked up to * 100000, it will take several seconds, depending on the CPU. */ for (j = 0; j < (i - start_uidpos); j++) if (check_dups[j] == pwd->pw_uid) { /* Found another entry for uid, so skip it */ fnd_dup = 1; break; } if (fnd_dup != 0) continue; check_dups[i - start_uidpos] = pwd->pw_uid; nid.nid_uid = pwd->pw_uid; nid.nid_name = pwd->pw_name; nid.nid_namelen = strlen(pwd->pw_name); nid.nid_flag = NFSID_ADDUID; #ifdef DEBUG printf("add uid=%d name=%s\n", nid.nid_uid, nid.nid_name); #else error = nfssvc(NFSSVC_IDNAME, &nid); if (error) errx(1, "Can't add user %s", pwd->pw_name); #endif i++; } /* * I should feel guilty for not calling this for all the above exit() * upon error cases, but I don't. */ if (mustfreeai) freeaddrinfo(aip); #ifdef DEBUG exit(0); #endif /* * Temporarily block SIGUSR1 and SIGCHLD, so slaves[] can't * end up bogus. */ sigemptyset(&signew); sigaddset(&signew, SIGUSR1); sigaddset(&signew, SIGCHLD); sigprocmask(SIG_BLOCK, &signew, NULL); daemon(0, 0); (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, SIG_IGN); (void)signal(SIGUSR1, cleanup_term); (void)signal(SIGCHLD, cleanup_term); openlog("nfsuserd:", LOG_PID, LOG_DAEMON); /* * Fork off the slave daemons that do the work. All the master * does is kill them off and cleanup. */ for (i = 0; i < nfsuserdcnt; i++) { slaves[i] = fork(); if (slaves[i] == 0) { im_a_slave = 1; setproctitle("slave"); sigemptyset(&signew); sigaddset(&signew, SIGUSR1); sigprocmask(SIG_UNBLOCK, &signew, NULL); /* * and away we go. */ svc_run(); syslog(LOG_ERR, "nfsuserd died: %m"); exit(1); } else if (slaves[i] < 0) { syslog(LOG_ERR, "fork: %m"); } } /* * Just wait for SIGUSR1 or a child to die and then... * As the Governor of California would say, "Terminate them". */ setproctitle("master"); sigemptyset(&signew); while (1) sigsuspend(&signew); }
/* * get_group_members - identify the users in a given group name * IN group_name - a single group name * RET a zero terminated list of its UIDs or NULL on error * NOTE: User root has implicitly access to every group * NOTE: The caller must xfree non-NULL return values */ extern uid_t *get_group_members(char *group_name) { char *grp_buffer = NULL; struct group grp, *grp_result = NULL; struct passwd *pwd_result = NULL; uid_t *group_uids = NULL, my_uid; gid_t my_gid; int buflen = PW_BUF_SIZE, i, j, res, uid_cnt; #ifdef HAVE_AIX FILE *fp = NULL; #elif defined (__APPLE__) || defined (__CYGWIN__) #else char pw_buffer[PW_BUF_SIZE]; struct passwd pw; #endif group_uids = _get_group_cache(group_name); if (group_uids) { /* We found in cache */ _log_group_members(group_name, group_uids); return group_uids; } #if defined(_SC_GETGR_R_SIZE_MAX) i = sysconf(_SC_GETGR_R_SIZE_MAX); buflen = MAX(buflen, i); #endif grp_buffer = xmalloc(buflen); while (1) { slurm_seterrno(0); res = getgrnam_r(group_name, &grp, grp_buffer, buflen, &grp_result); /* We need to check for !grp_result, since it appears some * versions of this function do not return an error on * failure. */ if (res != 0 || !grp_result) { if (errno == ERANGE) { buflen *= 2; xrealloc(grp_buffer, buflen); continue; } error("%s: Could not find configured group %s", __func__, group_name); xfree(grp_buffer); return NULL; } break; } my_gid = grp_result->gr_gid; j = 0; uid_cnt = 0; /* Get the members from the getgrnam_r() call. */ for (i = 0; grp_result->gr_mem[i]; i++) { if (uid_from_string(grp_result->gr_mem[i], &my_uid) < 0) { continue; } if (my_uid == 0) continue; if (j + 1 >= uid_cnt) { uid_cnt += 100; xrealloc(group_uids, (sizeof(uid_t) * uid_cnt)); } group_uids[j++] = my_uid; } #ifdef HAVE_AIX setgrent_r(&fp); while (1) { slurm_seterrno(0); res = getgrent_r(&grp, grp_buffer, buflen, &fp); if (res != 0) { if (errno == ERANGE) { buflen *= 2; xrealloc(grp_buffer, buflen); continue; } break; } grp_result = &grp; #elif defined (__APPLE__) || defined (__CYGWIN__) setgrent(); while (1) { if ((grp_result = getgrent()) == NULL) break; #else setgrent(); while (1) { /* MH-CEA workaround to handle different group entries with * the same gid */ slurm_seterrno(0); res = getgrent_r(&grp, grp_buffer, buflen, &grp_result); if (res != 0 || grp_result == NULL) { /* FreeBSD returns 0 and sets the grp_result to NULL * unlike linux which returns ENOENT. */ if (errno == ERANGE) { buflen *= 2; xrealloc(grp_buffer, buflen); continue; } break; } #endif if (grp_result->gr_gid == my_gid) { if (strcmp(grp_result->gr_name, group_name)) { debug("including members of group '%s' as it " "corresponds to the same gid as group" " '%s'",grp_result->gr_name,group_name); } for (i=0; grp_result->gr_mem[i]; i++) { if (uid_from_string(grp_result->gr_mem[i], &my_uid) < 0) { /* Group member without valid login */ continue; } if (my_uid == 0) continue; if (j+1 >= uid_cnt) { uid_cnt += 100; xrealloc(group_uids, (sizeof(uid_t) * uid_cnt)); } group_uids[j++] = my_uid; } } } #ifdef HAVE_AIX endgrent_r(&fp); setpwent_r(&fp); while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) { pwd_result = &pw; #else endgrent(); setpwent(); #if defined (__sun) while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) { #elif defined (__APPLE__) || defined (__CYGWIN__) while ((pwd_result = getpwent()) != NULL) { #else while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) { #endif #endif /* At eof FreeBSD returns 0 unlike Linux * which returns ENOENT. */ if (pwd_result == NULL) break; if (pwd_result->pw_gid != my_gid) continue; if (j+1 >= uid_cnt) { uid_cnt += 100; xrealloc(group_uids, (sizeof(uid_t) * uid_cnt)); } group_uids[j++] = pwd_result->pw_uid; } #ifdef HAVE_AIX endpwent_r(&fp); #else endpwent(); #endif xfree(grp_buffer); _put_group_cache(group_name, group_uids, j); _log_group_members(group_name, group_uids); return group_uids; } /* Delete our group/uid cache */ extern void clear_group_cache(void) { slurm_mutex_lock(&group_cache_mutex); FREE_NULL_LIST(group_cache_list); slurm_mutex_unlock(&group_cache_mutex); } /* Get a record from our group/uid cache. * Return NULL if not found. */ static uid_t *_get_group_cache(char *group_name) { ListIterator iter; struct group_cache_rec *cache_rec; uid_t *group_uids = NULL; int sz; slurm_mutex_lock(&group_cache_mutex); if (!group_cache_list) { slurm_mutex_unlock(&group_cache_mutex); return NULL; } iter = list_iterator_create(group_cache_list); while ((cache_rec = (struct group_cache_rec *) list_next(iter))) { if (strcmp(group_name, cache_rec->group_name)) continue; sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1); group_uids = (uid_t *) xmalloc(sz); memcpy(group_uids, cache_rec->group_uids, sz); break; } list_iterator_destroy(iter); slurm_mutex_unlock(&group_cache_mutex); return group_uids; } /* Delete a record from the group/uid cache, used by list functions */ static void _cache_del_func(void *x) { struct group_cache_rec *cache_rec; cache_rec = (struct group_cache_rec *) x; xfree(cache_rec->group_name); xfree(cache_rec->group_uids); xfree(cache_rec); } /* Put a record on our group/uid cache */ static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt) { struct group_cache_rec *cache_rec; int sz; slurm_mutex_lock(&group_cache_mutex); if (!group_cache_list) { group_cache_list = list_create(_cache_del_func); } sz = sizeof(uid_t) * (uid_cnt); cache_rec = xmalloc(sizeof(struct group_cache_rec)); cache_rec->group_name = xstrdup(group_name); cache_rec->uid_cnt = uid_cnt; cache_rec->group_uids = (uid_t *) xmalloc(sizeof(uid_t) + sz); if (uid_cnt > 0) memcpy(cache_rec->group_uids, group_uids, sz); list_append(group_cache_list, cache_rec); slurm_mutex_unlock(&group_cache_mutex); } static void _log_group_members(char *group_name, uid_t *group_uids) { #if _DEBUG int i; if ((group_uids == NULL) || (group_uids[0] == 0)) { info("Group %s has no users", group_name); return; } info("Group %s contains uids:", group_name); for (i=0; group_uids && group_uids[i]; i++) info(" %u", group_uids[i]); #endif }
int main(int argc, char *argv[]) { struct fstab *fs; struct passwd *pw; struct group *gr; int ch, gflag = 0, uflag = 0, errs = 0; long i, argnum, done = 0; while ((ch = getopt(argc, argv, "aghnuv")) != -1) { switch(ch) { case 'a': aflag++; break; case 'g': gflag++; break; case 'h': hflag++; break; case 'n': nflag++; break; case 'u': uflag++; break; case 'v': vflag++; break; default: usage(); } } argc -= optind; argv += optind; if (argc == 0 && !aflag) usage(); if (!gflag && !uflag) { if (aflag) gflag++; uflag++; } if (gflag && !nflag) { setgrent(); while ((gr = getgrent()) != 0) (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name); endgrent(); } if (uflag && !nflag) { setpwent(); while ((pw = getpwent()) != 0) (void) addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name); endpwent(); } setfsent(); while ((fs = getfsent()) != NULL) { if (strcmp(fs->fs_vfstype, "ufs")) continue; if (aflag) { if (gflag) errs += repquota(fs, GRPQUOTA); if (uflag) errs += repquota(fs, USRQUOTA); continue; } if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { done |= 1 << argnum; if (gflag) errs += repquota(fs, GRPQUOTA); if (uflag) errs += repquota(fs, USRQUOTA); } } endfsent(); for (i = 0; i < argc; i++) if ((done & (1 << i)) == 0) warnx("%s not found in fstab", argv[i]); exit(errs); }
int main(int argc, char **argv) { struct group *group; char **tmp_mem; int test_gid; fprintf(stdout, "Beginning test of libc/grp...\n"); fprintf(stdout, "=> Testing setgrent(), getgrent(), endgrent()...\n"); fprintf(stdout, "-> setgrent()...\n"); setgrent(); fprintf(stdout, "-> getgrent()...\n"); printf ("********************************************************************************\n"); while ((group = getgrent()) != NULL) { printf("gr_name\t\t: %s\n", group->gr_name); printf("gr_passwd\t: %s\n", group->gr_passwd); printf("gr_gid\t\t: %d\n", (int) group->gr_gid); printf("gr_mem\t\t: "); fflush(stdout); tmp_mem = group->gr_mem; while (*tmp_mem != NULL) { printf("%s, ", *tmp_mem); tmp_mem++; } printf ("\n********************************************************************************\n"); } fprintf(stdout, "-> endgrent()...\n"); endgrent(); fprintf(stdout, "=> Test of setgrent(), getgrent(), endgrent() complete.\n"); fprintf(stdout, "=> Testing getgrid(), getgrnam()...\n"); fprintf(stdout, "-> getgrgid()...\n"); printf ("********************************************************************************\n"); for (test_gid = 0; test_gid < 100; test_gid++) { fprintf(stdout, "-> getgrgid(%d)...\n", test_gid); group = getgrgid((gid_t) test_gid); if (group != NULL) { printf("gr_name\t: %s\n", group->gr_name); printf("gr_passwd\t: %s\n", group->gr_passwd); printf("gr_gid\t: %d\n", (int) group->gr_gid); printf("gr_mem\t\t: "); fflush(stdout); tmp_mem = group->gr_mem; while (*tmp_mem != NULL) { printf("%s, ", *tmp_mem); tmp_mem++; } } printf ("\n********************************************************************************\n"); } fprintf(stdout, "-> getgrnam()...\n"); group = getgrnam("root"); if (group == NULL) { printf(">NULL<\n"); } else { printf("gr_name\t: %s\n", group->gr_name); printf("gr_passwd\t: %s\n", group->gr_passwd); printf("gr_gid\t: %d\n", (int) group->gr_gid); printf("gr_mem\t\t: "); fflush(stdout); tmp_mem = group->gr_mem; while (*tmp_mem != NULL) { printf("%s, ", *tmp_mem); tmp_mem++; } printf("\n"); } return 0; }
KDModule::KDModule(QWidget *parent, const char *name, const QStringList &) : KCModule(KDMFactory::instance(), parent, name), minshowuid(0), maxshowuid(0), updateOK(false) { KAboutData *about = new KAboutData(I18N_NOOP("kcmkdm"), I18N_NOOP("KDE Login Manager Config Module"), 0, 0, KAboutData::License_GPL, I18N_NOOP("(c) 1996 - 2005 The KDM Authors")); about->addAuthor("Thomas Tanghus", I18N_NOOP("Original author"), "*****@*****.**"); about->addAuthor("Steffen Hansen", 0, "*****@*****.**"); about->addAuthor("Oswald Buddenhagen", I18N_NOOP("Current maintainer"), "*****@*****.**"); setQuickHelp( i18n("<h1>Login Manager</h1> In this module you can configure the " "various aspects of the KDE Login Manager. This includes " "the look and feel as well as the users that can be " "selected for login. Note that you can only make changes " "if you run the module with superuser rights. If you have not started the KDE " "Control Center with superuser rights (which is absolutely the right thing to " "do, by the way), click on the <em>Modify</em> button to acquire " "superuser rights. You will be asked for the superuser password." "<h2>Appearance</h2> On this tab page, you can configure how " "the Login Manager should look, which language it should use, and which " "GUI style it should use. The language settings made here have no influence on " "the user's language settings." "<h2>Font</h2>Here you can choose the fonts that the Login Manager should use " "for various purposes like greetings and user names. " "<h2>Background</h2>If you want to set a special background for the login " "screen, this is where to do it." "<h2>Shutdown</h2> Here you can specify who is allowed to shutdown/reboot the machine " "and whether a boot manager should be used." "<h2>Users</h2>On this tab page, you can select which users the Login Manager " "will offer you for logging in." "<h2>Convenience</h2> Here you can specify a user to be logged in automatically, " "users not needing to provide a password to log in, and other convenience features.<br>" "Note, that these settings are security holes by their nature, so use them very carefully.")); setAboutData(about); setlocale(LC_COLLATE, "C"); KGlobal::locale()->insertCatalogue("kcmbackground"); QStringList sl; QMap< gid_t, QStringList > tgmap; QMap< gid_t, QStringList >::Iterator tgmapi; QMap< gid_t, QStringList >::ConstIterator tgmapci; QMap< QString, QPair< int, QStringList > >::Iterator umapi; struct passwd *ps; for(setpwent(); (ps = getpwent());) { QString un(QFile::decodeName(ps->pw_name)); if(usermap.find(un) == usermap.end()) { usermap.insert(un, QPair< int, QStringList >(ps->pw_uid, sl)); if((tgmapi = tgmap.find(ps->pw_gid)) != tgmap.end()) (*tgmapi).append(un); else tgmap[ps->pw_gid] = un; } } endpwent(); struct group *grp; for(setgrent(); (grp = getgrent());) { QString gn(QFile::decodeName(grp->gr_name)); bool delme = false; if((tgmapi = tgmap.find(grp->gr_gid)) != tgmap.end()) { if((*tgmapi).count() == 1 && (*tgmapi).first() == gn) delme = true; else for(QStringList::ConstIterator it = (*tgmapi).begin(); it != (*tgmapi).end(); ++it) usermap[*it].second.append(gn); tgmap.remove(tgmapi); } if(!*grp->gr_mem || (delme && !grp->gr_mem[1] && gn == QFile::decodeName(*grp->gr_mem))) continue; do { QString un(QFile::decodeName(*grp->gr_mem)); if((umapi = usermap.find(un)) != usermap.end()) { if((*umapi).second.find(gn) == (*umapi).second.end()) (*umapi).second.append(gn); } else kdWarning() << "group '" << gn << "' contains unknown user '" << un << "'" << endl; } while(*++grp->gr_mem); } endgrent(); for(tgmapci = tgmap.begin(); tgmapci != tgmap.end(); ++tgmapci) kdWarning() << "user(s) '" << tgmapci.data().join(",") << "' have unknown GID " << tgmapci.key() << endl; config = new KSimpleConfig(QString::fromLatin1(KDE_CONFDIR "/kdm/kdmrc")); QVBoxLayout *top = new QVBoxLayout(this); tab = new QTabWidget(this); // ***** // _don't_ add a theme configurator until the theming engine is _really_ done!! // ***** appearance = new KDMAppearanceWidget(this); tab->addTab(appearance, i18n("A&ppearance")); connect(appearance, SIGNAL(changed(bool)), SIGNAL(changed(bool))); font = new KDMFontWidget(this); tab->addTab(font, i18n("&Font")); connect(font, SIGNAL(changed(bool)), SIGNAL(changed(bool))); background = new KBackground(this); tab->addTab(background, i18n("&Background")); connect(background, SIGNAL(changed(bool)), SIGNAL(changed(bool))); sessions = new KDMSessionsWidget(this); tab->addTab(sessions, i18n("&Shutdown")); connect(sessions, SIGNAL(changed(bool)), SIGNAL(changed(bool))); users = new KDMUsersWidget(this, 0); tab->addTab(users, i18n("&Users")); connect(users, SIGNAL(changed(bool)), SIGNAL(changed(bool))); connect(users, SIGNAL(setMinMaxUID(int, int)), SLOT(slotMinMaxUID(int, int))); connect(this, SIGNAL(addUsers(const QMap< QString, int > &)), users, SLOT(slotAddUsers(const QMap< QString, int > &))); connect(this, SIGNAL(delUsers(const QMap< QString, int > &)), users, SLOT(slotDelUsers(const QMap< QString, int > &))); connect(this, SIGNAL(clearUsers()), users, SLOT(slotClearUsers())); convenience = new KDMConvenienceWidget(this, 0); tab->addTab(convenience, i18n("Con&venience")); connect(convenience, SIGNAL(changed(bool)), SIGNAL(changed(bool))); connect(this, SIGNAL(addUsers(const QMap< QString, int > &)), convenience, SLOT(slotAddUsers(const QMap< QString, int > &))); connect(this, SIGNAL(delUsers(const QMap< QString, int > &)), convenience, SLOT(slotDelUsers(const QMap< QString, int > &))); connect(this, SIGNAL(clearUsers()), convenience, SLOT(slotClearUsers())); load(); if(getuid() != 0 || !config->checkConfigFilesWritable(true)) { appearance->makeReadOnly(); font->makeReadOnly(); background->makeReadOnly(); users->makeReadOnly(); sessions->makeReadOnly(); convenience->makeReadOnly(); } top->addWidget(tab); }
/* * get_group_members - identify the users in a given group name * IN group_name - a single group name * RET a zero terminated list of its UIDs or NULL on error * NOTE: User root has implicitly access to every group * NOTE: The caller must xfree non-NULL return values */ extern uid_t *get_group_members(char *group_name) { char grp_buffer[PW_BUF_SIZE]; struct group grp, *grp_result = NULL; struct passwd *pwd_result = NULL; uid_t *group_uids = NULL, my_uid; gid_t my_gid; int i, j, uid_cnt; #ifdef HAVE_AIX FILE *fp = NULL; #elif defined (__APPLE__) || defined (__CYGWIN__) #else char pw_buffer[PW_BUF_SIZE]; struct passwd pw; #endif group_uids = _get_group_cache(group_name); if (group_uids) { /* We found in cache */ _log_group_members(group_name, group_uids); return group_uids; } /* We need to check for !grp_result, since it appears some * versions of this function do not return an error on failure. */ if (getgrnam_r(group_name, &grp, grp_buffer, PW_BUF_SIZE, &grp_result) || (grp_result == NULL)) { error("Could not find configured group %s", group_name); return NULL; } my_gid = grp_result->gr_gid; j = 0; uid_cnt = 0; #ifdef HAVE_AIX setgrent_r(&fp); while (!getgrent_r(&grp, grp_buffer, PW_BUF_SIZE, &fp)) { grp_result = &grp; #elif defined (__APPLE__) || defined (__CYGWIN__) setgrent(); while ((grp_result = getgrent()) != NULL) { #else setgrent(); while (getgrent_r(&grp, grp_buffer, PW_BUF_SIZE, &grp_result) == 0 && grp_result != NULL) { #endif if (grp_result->gr_gid == my_gid) { if (strcmp(grp_result->gr_name, group_name)) { debug("including members of group '%s' as it " "corresponds to the same gid as group" " '%s'",grp_result->gr_name,group_name); } for (i=0; grp_result->gr_mem[i]; i++) { if (uid_from_string(grp_result->gr_mem[i], &my_uid) < 0) { /* Group member without valid login */ continue; } if (my_uid == 0) continue; if (j+1 >= uid_cnt) { uid_cnt += 100; xrealloc(group_uids, (sizeof(uid_t) * uid_cnt)); } group_uids[j++] = my_uid; } } } #ifdef HAVE_AIX endgrent_r(&fp); setpwent_r(&fp); while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) { pwd_result = &pw; #else endgrent(); setpwent(); #if defined (__sun) while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) { #elif defined (__APPLE__) || defined (__CYGWIN__) while ((pwd_result = getpwent()) != NULL) { #else while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) { #endif #endif if (pwd_result->pw_gid != my_gid) continue; if (j+1 >= uid_cnt) { uid_cnt += 100; xrealloc(group_uids, (sizeof(uid_t) * uid_cnt)); } group_uids[j++] = pwd_result->pw_uid; } #ifdef HAVE_AIX endpwent_r(&fp); #else endpwent(); #endif _put_group_cache(group_name, group_uids, j); _log_group_members(group_name, group_uids); return group_uids; } /* Delete our group/uid cache */ extern void clear_group_cache(void) { pthread_mutex_lock(&group_cache_mutex); if (group_cache_list) { list_destroy(group_cache_list); group_cache_list = NULL; } pthread_mutex_unlock(&group_cache_mutex); } /* Get a record from our group/uid cache. * Return NULL if not found. */ static uid_t *_get_group_cache(char *group_name) { ListIterator iter; struct group_cache_rec *cache_rec; uid_t *group_uids = NULL; int sz; pthread_mutex_lock(&group_cache_mutex); if (!group_cache_list) { pthread_mutex_unlock(&group_cache_mutex); return NULL; } iter = list_iterator_create(group_cache_list); if (!iter) fatal("list_iterator_create: malloc failure"); while ((cache_rec = (struct group_cache_rec *) list_next(iter))) { if (strcmp(group_name, cache_rec->group_name)) continue; sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1); group_uids = (uid_t *) xmalloc(sz); memcpy(group_uids, cache_rec->group_uids, sz); break; } list_iterator_destroy(iter); pthread_mutex_unlock(&group_cache_mutex); return group_uids; } /* Delete a record from the group/uid cache, used by list functions */ static void _cache_del_func(void *x) { struct group_cache_rec *cache_rec; cache_rec = (struct group_cache_rec *) x; xfree(cache_rec->group_name); xfree(cache_rec->group_uids); xfree(cache_rec); } /* Put a record on our group/uid cache */ static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt) { struct group_cache_rec *cache_rec; int sz; pthread_mutex_lock(&group_cache_mutex); if (!group_cache_list) { group_cache_list = list_create(_cache_del_func); if (!group_cache_list) fatal("list_create: malloc failure:"); } sz = sizeof(uid_t) * (uid_cnt); cache_rec = xmalloc(sizeof(struct group_cache_rec)); cache_rec->group_name = xstrdup(group_name); cache_rec->uid_cnt = uid_cnt; cache_rec->group_uids = (uid_t *) xmalloc(sizeof(uid_t) + sz); if (uid_cnt > 0) memcpy(cache_rec->group_uids, group_uids, sz); list_append(group_cache_list, cache_rec); pthread_mutex_unlock(&group_cache_mutex); } static void _log_group_members(char *group_name, uid_t *group_uids) { #if _DEBUG int i; if ((group_uids == NULL) || (group_uids[0] == 0)) { info("Group %s has no users", group_name); return; } info("Group %s contains uids:", group_name); for (i=0; group_uids && group_uids[i]; i++) info(" %u", group_uids[i]); #endif }