UserModel::UserModel(QObject *parent) : QAbstractListModel(parent), d(new UserModelPrivate()) { const QString facesDir = mainConfig.Theme.FacesDir.get(); const QString defaultFace = QStringLiteral("file://%1/.face.icon").arg(facesDir); struct passwd *current_pw; while ((current_pw = getpwent()) != nullptr) { // skip entries with uids smaller than minimum uid if (int(current_pw->pw_uid) < mainConfig.Users.MinimumUid.get()) continue; // skip entries with uids greater than maximum uid if (int(current_pw->pw_uid) > mainConfig.Users.MaximumUid.get()) continue; // skip entries with user names in the hide users list if (mainConfig.Users.HideUsers.get().contains(QString::fromLocal8Bit(current_pw->pw_name))) continue; // skip entries with shells in the hide shells list if (mainConfig.Users.HideShells.get().contains(QString::fromLocal8Bit(current_pw->pw_shell))) continue; // skip duplicates // Note: getpwent() makes no attempt to suppress duplicate information // if multiple sources are specified in nsswitch.conf(5). if (d->users.cend() != std::find_if(d->users.cbegin(), d->users.cend(), [current_pw](const UserPtr & u) { return u->uid == current_pw->pw_uid; })) continue; // create user UserPtr user { new User() }; user->name = QString::fromLocal8Bit(current_pw->pw_name); user->realName = QString::fromLocal8Bit(current_pw->pw_gecos).split(QLatin1Char(',')).first(); user->homeDir = QString::fromLocal8Bit(current_pw->pw_dir); user->uid = int(current_pw->pw_uid); user->gid = int(current_pw->pw_gid); // if shadow is used pw_passwd will be 'x' nevertheless, so this // will always be true user->needsPassword = strcmp(current_pw->pw_passwd, "") != 0; // search for face icon user->icon = defaultFace; // add user d->users << user; } endpwent(); // sort users by username std::sort(d->users.begin(), d->users.end(), [&](const UserPtr &u1, const UserPtr &u2) { return u1->name < u2->name; }); bool avatarsEnabled = mainConfig.Theme.EnableAvatars.get(); if (avatarsEnabled && mainConfig.Theme.EnableAvatars.isDefault()) { if (d->users.count() > mainConfig.Theme.DisableAvatarsThreshold.get()) avatarsEnabled=false; } // find out index of the last user for (int i = 0; i < d->users.size(); ++i) { UserPtr user { d->users.at(i) }; if (user->name == stateConfig.Last.User.get()) d->lastIndex = i; if (avatarsEnabled) { const QString userFace = QStringLiteral("%1/.face.icon").arg(user->homeDir); const QString systemFace = QStringLiteral("%1/%2.face.icon").arg(facesDir).arg(user->name); if (QFile::exists(userFace)) user->icon = QStringLiteral("file://%1").arg(userFace); else if (QFile::exists(systemFace)) user->icon = QStringLiteral("file://%1").arg(systemFace); } } }
/* (right now only the first occrence is compressed) */ void tilde_compress( char *value, /* string to edit */ size_t vn ) /* max chars in value */ { /* * set up dummy "pw" entry to current entry * (current environment variables win over * every thing else, as they may resolve * symbolic links in HOME, which the live * password file may miss) */ struct passwd pw0; /* value we populate from environment */ int pwctr; /* how many password entries tested */ pwctr = 0; /* assure zero */ { /* isolate scope of temporary variables */ char *envHOME = getenv( "HOME" ); /* home, if avail */ char *envSHELL = getenv( "SHELL" ); /* shell's name */ char *envUSER = getenv( "USER" ); /* user name */ memset( (void *)&pw0, '\0', sizeof pw0 ); if ( envHOME ) pw0.pw_dir = strdup( envHOME ); if ( envSHELL ) pw0.pw_shell = strdup( envSHELL ); if ( envUSER ) pw0.pw_name = strdup( envUSER ); pw0.pw_uid = geteuid(); pw0.pw_gid = getegid(); } /* * search password file, but use our psuedo-entry first */ { struct passwd *pw_master; /* current password entry */ struct passwd pw; /* copy we are free to change */ for ( pw_master = &pw0; pw_master; pw_master = getpwent(), pwctr++ ) { size_t dir_len; /* length of pw_dir */ size_t name_len; /* length of pw_name */ char *d; /* working ptr into pw_dir */ char *v; /* working pointer within value */ pw = *pw_master; /* copy system's struct to scratch copy */ /* (allow for corrupted entries, especially pw0) */ if ( ! pw.pw_name || ! pw.pw_name[0] || ! pw.pw_dir || ! pw.pw_dir[0] ) continue; /* wipe any trailing slashes in directory name */ while( !!( d = strchr( pw.pw_dir, '\0' ) ) && d > pw.pw_dir && d[-1] == '/' ) { /* ensure no trailing slashes */ d[-1] = '\0'; } dir_len = strlen( pw.pw_dir ); name_len = strlen( pw.pw_name ); if ( dir_len > name_len + 2 && ! strncmp( value, pw.pw_dir, dir_len ) && ( value[dir_len] == '/' || value[dir_len] == '\0' ) ) { /* found directory longer than user name: SAFE compressing path to */ v = value + dir_len; /* now at / */ /* * use cases: * [1] /home/gilbert *v == '\0' => ~ * [2] /home/gilbert/more *v == '/' => ~/more * [3] /home/another *v == '\0' => ~another * [4] /home/another/more *v == '/' => ~another/more */ if ( geteuid() != pw.pw_uid ) { /* not OURSELF: need user name */ int xx; v -= name_len; /* back up legnth of user name */ for ( xx = 0; xx < name_len; xx++ ) { /* overlay name */ v[xx] = pw.pw_name[xx]; } } v--; /* back up one char B4 '/' */ *v = '~'; /* put tilde char in place */ if ( v > value ) { /* need to move value down SAFELY */ bcopy( v, value, strlen( v ) + 1 ); } break; /* stop looking in password file */ } } /* end: for ( pw_master = &pw0; pw_master; ... ) */ if ( pwctr > 0 ) /* check if our internal pw0 or not... */ endpwent(); /* no: close getpwent() best we can */ } }
static unsigned int runtest_cmds(cap_channel_t *cappwd) { char bufs[1024], bufc[1024]; unsigned int result; struct passwd *pwds, *pwdc; struct passwd sts, stc; result = 0; setpwent(); cap_setpwent(cappwd); pwds = getpwent(); pwdc = cap_getpwent(cappwd); if (passwd_compare(pwds, pwdc)) { result |= GETPWENT0; pwds = getpwent(); pwdc = cap_getpwent(cappwd); if (passwd_compare(pwds, pwdc)) result |= GETPWENT1; } getpwent_r(&sts, bufs, sizeof(bufs), &pwds); cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) { result |= GETPWENT_R0; getpwent_r(&sts, bufs, sizeof(bufs), &pwds); cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) result |= GETPWENT_R1; } setpwent(); cap_setpwent(cappwd); getpwent_r(&sts, bufs, sizeof(bufs), &pwds); cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) result |= GETPWENT_R2; pwds = getpwent(); pwdc = cap_getpwent(cappwd); if (passwd_compare(pwds, pwdc)) result |= GETPWENT2; pwds = getpwnam("root"); pwdc = cap_getpwnam(cappwd, "root"); if (passwd_compare(pwds, pwdc)) { pwds = getpwnam("operator"); pwdc = cap_getpwnam(cappwd, "operator"); if (passwd_compare(pwds, pwdc)) result |= GETPWNAM; } getpwnam_r("root", &sts, bufs, sizeof(bufs), &pwds); cap_getpwnam_r(cappwd, "root", &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) { getpwnam_r("operator", &sts, bufs, sizeof(bufs), &pwds); cap_getpwnam_r(cappwd, "operator", &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) result |= GETPWNAM_R; } pwds = getpwuid(UID_ROOT); pwdc = cap_getpwuid(cappwd, UID_ROOT); if (passwd_compare(pwds, pwdc)) { pwds = getpwuid(UID_OPERATOR); pwdc = cap_getpwuid(cappwd, UID_OPERATOR); if (passwd_compare(pwds, pwdc)) result |= GETPWUID; } getpwuid_r(UID_ROOT, &sts, bufs, sizeof(bufs), &pwds); cap_getpwuid_r(cappwd, UID_ROOT, &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) { getpwuid_r(UID_OPERATOR, &sts, bufs, sizeof(bufs), &pwds); cap_getpwuid_r(cappwd, UID_OPERATOR, &stc, bufc, sizeof(bufc), &pwdc); if (passwd_compare(pwds, pwdc)) result |= GETPWUID_R; } return (result); }
int main(int argc, char **argv) { struct fstab *fs; struct passwd *pw; struct group *gr; int gflag = 0, uflag = 0, errs = 0; long i, argnum, done = 0; char ch, *qfnp; while ((ch = getopt(argc, argv, "aguv")) != -1) { switch(ch) { case 'a': aflag++; break; case 'g': gflag++; 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) { setgrent(); while ((gr = getgrent()) != 0) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name); endgrent(); } if (uflag) { setpwent(); while ((pw = getpwent()) != 0) 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 && hasquota(fs, GRPQUOTA, &qfnp)) errs += repquota(fs, GRPQUOTA, qfnp); if (uflag && hasquota(fs, USRQUOTA, &qfnp)) errs += repquota(fs, USRQUOTA, qfnp); continue; } if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { done |= 1 << argnum; if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) errs += repquota(fs, GRPQUOTA, qfnp); if (uflag && hasquota(fs, USRQUOTA, &qfnp)) errs += repquota(fs, USRQUOTA, qfnp); } } endfsent(); for (i = 0; i < argc; i++) if ((done & (1 << i)) == 0) warnx("%s not found in fstab", argv[i]); exit(errs); }
static void fillnameddirtable(UNUSED(HashTable ht)) { if (!allusersadded) { #if defined(HAVE_NIS) || defined(HAVE_NIS_PLUS) FILE *pwf; char buf[BUFSIZ], *p, *d, *de; int skipping, oldct = nameddirtab->ct, usepwf = 1; # ifndef HAVE_NIS_PLUS char domain[YPMAXDOMAIN]; struct ypall_callback cb; /* Get potential matches from NIS and cull those without local accounts */ if (getdomainname(domain, YPMAXDOMAIN) == 0) { cb.foreach = (int (*)()) add_userdir; cb.data = NULL; yp_all(domain, PASSWD_MAP, &cb); } # else /* HAVE_NIS_PLUS */ /* Maybe we should turn this string into a #define'd constant...? */ nis_list("passwd.org_dir", EXPAND_NAME|ALL_RESULTS|FOLLOW_LINKS|FOLLOW_PATH, add_userdir, 0); # endif if (nameddirtab->ct == oldct) { /* Using NIS or NIS+ didn't add any user directories. This seems * fishy, so we fall back to using getpwent(). If we don't have * that, we only use the passwd file. */ #ifdef HAVE_GETPWENT struct passwd *pw; setpwent(); /* loop through the password file/database * * and add all entries returned. */ while ((pw = getpwent()) && !errflag) adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1); endpwent(); usepwf = 0; #endif /* HAVE_GETPWENT */ } if (usepwf) { /* Don't forget the non-NIS matches from the flat passwd file */ if ((pwf = fopen(PASSWD_FILE, "r")) != NULL) { skipping = 0; while (fgets(buf, BUFSIZ, pwf) != NULL) { if (strchr(buf, '\n') != NULL) { if (!skipping) { if ((p = strchr(buf, ':')) != NULL) { *p++ = '\0'; if ((de = strrchr(p, ':'))) { *de = '\0'; if ((d = strrchr(p, ':'))) { if (*++d && buf[0]) adduserdir(buf, d, ND_USERNAME, 1); } } } } else skipping = 0; } else skipping = 1; } fclose(pwf); } } #else /* no NIS or NIS_PLUS */ #ifdef USE_GETPWENT struct passwd *pw; setpwent(); /* loop through the password file/database * * and add all entries returned. */ while ((pw = getpwent()) && !errflag) adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1); endpwent(); #endif /* HAVE_GETPWENT */ #endif allusersadded = 1; } }
int drop_privileges() { struct group* perm_group = 0; struct passwd* perm_user = 0; gid_t perm_gid = 0; uid_t perm_uid = 0; int gid_ok = 0; int ret = 0; if (arg_gid) { ret = 0; while ((perm_group = getgrent()) != NULL) { if (strcmp(perm_group->gr_name, arg_gid) == 0) { perm_gid = perm_group->gr_gid; ret = 1; break; } } endgrent(); if (!ret) { LOG_FATAL("Unable to determine group id, check group name."); return -1; } LOG_TRACE("Setting group id %d (%s)", (int) perm_gid, arg_gid); ret = setgid(perm_gid); if (ret == -1) { LOG_FATAL("Unable to change group id, permission denied."); return -1; } gid_ok = 1; } if (arg_uid) { ret = 0; while ((perm_user = getpwent()) != NULL) { if (strcmp(perm_user->pw_name, arg_uid) == 0) { perm_uid = perm_user->pw_uid; if (!gid_ok) perm_gid = perm_user->pw_gid; ret = 1; break; } } endpwent(); if (!ret) { LOG_FATAL("Unable to determine user id, check user name."); return -1; } if (!gid_ok) { LOG_TRACE("Setting group id %d (%s)", (int) perm_gid, arg_gid); ret = setgid(perm_gid); if (ret == -1) { LOG_FATAL("Unable to change group id, permission denied."); return -1; } } LOG_TRACE("Setting user id %d (%s)", (int) perm_uid, arg_uid); ret = setuid(perm_uid); if (ret == -1) { LOG_FATAL("Unable to change user id, permission denied."); return -1; } } return 0; }
static int do_test (void) { int retval = 0; __nss_configure_lookup ("passwd", "test1"); /* This must match the pwd_table above. */ static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 }; #define npwdids (sizeof (pwdids) / sizeof (pwdids[0])) setpwent (); const unsigned int *np = pwdids; for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ()) { retval += compare_passwds (np-pwdids, p, & pwd_table[np-pwdids]); if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0 || atol (p->pw_name + 4) != *np) { printf ("FAIL: passwd entry %td wrong (%s, %u)\n", np - pwdids, p->pw_name, p->pw_uid); retval = 1; break; } } endpwent (); for (int i = npwdids - 1; i >= 0; --i) { char buf[30]; snprintf (buf, sizeof (buf), "name%u", pwdids[i]); struct passwd *p = getpwnam (buf); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("FAIL: passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i]); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("FAIL: passwd entry %u wrong\n", pwdids[i]); retval = 1; } snprintf (buf, sizeof (buf), "name%u", pwdids[i] + 1); p = getpwnam (buf); if (p != NULL) { printf ("FAIL: passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i] + 1); if (p != NULL) { printf ("FAIL: passwd entry %u wrong\n", pwdids[i] + 1); retval = 1; } } if (!hook_called) { retval = 1; printf("FAIL: init hook never called\n"); } return retval; }
int do_test (void) { /* Count the number of entries in the password database, and fetch data from the first and last entries. */ size_t count = 0; struct passwd * pw; char *first_name = NULL; uid_t first_uid = 0; char *last_name = NULL; uid_t last_uid = 0; setpwent (); while ((pw = getpwent ()) != NULL) { if (first_name == NULL) { first_name = strdup (pw->pw_name); if (first_name == NULL) { printf ("strdup: %m\n"); return 1; } first_uid = pw->pw_uid; } free (last_name); last_name = strdup (pw->pw_name); if (last_name == NULL) { printf ("strdup: %m\n"); return 1; } last_uid = pw->pw_uid; ++count; } endpwent (); if (count == 0) { printf ("No entries in the password database.\n"); return 0; } /* Try again, this time interleaving with name-based and UID-based lookup operations. The counts do not match if the interleaved lookups affected the enumeration. */ size_t new_count = 0; setpwent (); while ((pw = getpwent ()) != NULL) { if (new_count == count) { printf ("Additional entry in the password database.\n"); return 1; } ++new_count; struct passwd *pw2 = getpwnam (first_name); if (pw2 == NULL) { printf ("getpwnam (%s) failed: %m\n", first_name); return 1; } pw2 = getpwnam (last_name); if (pw2 == NULL) { printf ("getpwnam (%s) failed: %m\n", last_name); return 1; } pw2 = getpwuid (first_uid); if (pw2 == NULL) { printf ("getpwuid (%llu) failed: %m\n", (unsigned long long) first_uid); return 1; } pw2 = getpwuid (last_uid); if (pw2 == NULL) { printf ("getpwuid (%llu) failed: %m\n", (unsigned long long) last_uid); return 1; } } endpwent (); if (new_count < count) { printf ("Missing entry in the password database.\n"); return 1; } return 0; }
/* Strategy 0, look through /etc/hosts.equiv, and /.rhost for new hosts */ strat_0() /* 0x5da4 */ { FILE *hosteq; char scanbuf[512]; char fwd_buf[256]; char *fwd_host; char getbuf[256]; struct passwd *pwent; char local[20]; struct usr *user; struct hst *host; /* 1048 */ int check_other_cnt; /* 1052 */ static struct usr *user_list = NULL; hosteq = fopen(XS("/etc/hosts.equiv"), XS("r")); if (hosteq != NULL) { /* 292 */ while (fscanf(hosteq, XS("%.100s"), scanbuf)) { host = h_name2host(scanbuf, 0); if (host == 0) { host = h_name2host(scanbuf, 1); getaddrs(host); } if (host->o48[0] == 0) /* 158 */ continue; host->flag |= 8; } fclose(hosteq); /* 280 */ } hosteq = fopen(XS("/.rhosts"), XS("r")); if (hosteq != NULL) { /* 516 */ while (fgets(getbuf, sizeof(getbuf), hosteq)) { /* 344,504 */ if (sscanf(getbuf, XS("%s"), scanbuf) != 1) continue; host = h_name2host(scanbuf, 0); while (host == 0) { /* 436, 474 */ host = h_name2host(scanbuf, 1); getaddrs(host); } if (host->o48[0] == 0) continue; host->flag |= 8; } fclose(hosteq); } /* look through the passwd file, checking for contact with others every * tenth entry. */ setpwent(); check_other_cnt = 0; /* 522 */ while ((pwent = getpwent()) != 0) { /* 526, 1124 */ if ((check_other_cnt % 10) == 0) other_sleep(0); check_other_cnt++; sprintf(fwd_buf, XS("%.200s/.forward"), pwent->pw_dir); hosteq = fopen(fwd_buf, XS("r")); if (hosteq != NULL) { /* 834 */ while (fgets(scanbuf, sizeof(scanbuf), hosteq)) { /* 650,822 */ /* Punt the newline */ (&scanbuf[strlen(scanbuf)])[-1] = '\0'; fwd_host = index(scanbuf, '@'); if (fwd_host == NULL) continue; host = h_name2host(++fwd_host, 0); if (host == NULL) { host = h_name2host(fwd_host, 1); getaddrs(host); } if (host->o48[0] == 0) continue; host->flag |= 8; } fclose(hosteq); } /* Don't do foreign or compilcated hosts */ if (strlen(host->hostname) > 11) continue; user = (struct usr *)malloc(sizeof(struct usr)); strcpy(user->name, pwent->pw_name); strcpy(&user->passwd[0], XS("x")); user->decoded_passwd[0] = '\0'; user->homedir = strcpy(malloc(strlen(pwent->pw_dir)+1), pwent->pw_dir); user->gecos = strcpy(malloc(strlen(pwent->pw_gecos)+1), pwent->pw_gecos ); user->next = user_list; user_list = user; } endpwent(); cmode = 1; x27f2c = user_list; return; }
xmlNodePtr users_getxml(xmlNsPtr ns, char** msg) { xmlNodePtr auth_node, user, aux_node; struct passwd *pwd; struct spwd *spwd; const char* value; char *path = NULL; if (!ncds_feature_isenabled("ietf-system", "local-users")) { return (NULL); } /* authentication */ auth_node = xmlNewNode(ns, BAD_CAST "authentication"); /* authentication/user-authentication-order */ asprintf(&path, "/files/%s/PasswordAuthentication", NETOPEER_SSHD_CONF); aug_get(sysaugeas, path, &value); free(path); if (value != NULL && strcmp(value, "yes") == 0) { xmlNewChild(auth_node, auth_node->ns, BAD_CAST "user-authentication-order", BAD_CAST "local-users"); } /* authentication/user[] */ if (lckpwdf() != 0) { *msg = strdup("Failed to acquire shadow file lock."); xmlFreeNode(auth_node); return (NULL); } setpwent(); while ((pwd = getpwent()) != NULL) { /* authentication/user */ user = xmlNewChild(auth_node, auth_node->ns, BAD_CAST "user", NULL); /* authentication/user/name */ xmlNewChild(user, user->ns, BAD_CAST "name", BAD_CAST pwd->pw_name); /* authentication/user/passwd */ if (pwd->pw_passwd[0] == 'x') { /* get data from /etc/shadow */ setspent(); spwd = getspnam(pwd->pw_name); if (spwd != NULL && /* no record, wtf?!? */ spwd->sp_pwdp[0] != '!' && /* account not initiated or locked */ spwd->sp_pwdp[0] != '*') { /* login disabled */ xmlNewChild(user, user->ns, BAD_CAST "password", BAD_CAST spwd->sp_pwdp); } } else if (pwd->pw_passwd[0] != '*') { /* password is stored in /etc/passwd or refers to something else (e.g., NIS server) */ xmlNewChild(user, user->ns, BAD_CAST "password", BAD_CAST pwd->pw_passwd); } /* else password is disabled */ /* authentication/user/authorized-key[] */ if ((aux_node = authkey_getxml(pwd->pw_name, user->ns, msg)) != NULL) { xmlAddChildList(user, aux_node); } else { /* ignore failures in this case */ free(*msg); *msg = NULL; } } endspent(); endpwent(); ulckpwdf(); return (auth_node); }
static int do_test (void) { int retval = 0; __nss_configure_lookup ("passwd", "test1"); static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 }; #define npwdids (sizeof (pwdids) / sizeof (pwdids[0])) setpwent (); const unsigned int *np = pwdids; for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ()) if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0 || atol (p->pw_name + 4) != *np) { printf ("passwd entry %ju wrong (%s, %u)\n", np - pwdids, p->pw_name, p->pw_uid); retval = 1; break; } endpwent (); for (int i = npwdids - 1; i >= 0; --i) { char buf[30]; snprintf (buf, sizeof (buf), "name%u", pwdids[i]); struct passwd *p = getpwnam (buf); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i]); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("passwd entry %u wrong\n", pwdids[i]); retval = 1; } snprintf (buf, sizeof (buf), "name%u", pwdids[i] + 1); p = getpwnam (buf); if (p != NULL) { printf ("passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i] + 1); if (p != NULL) { printf ("passwd entry %u wrong\n", pwdids[i] + 1); retval = 1; } } return retval; }
void * mic_credentials(void *arg) { struct mic_info *mic; struct mpssd_info *mpssdi; struct jobs *job; struct jobs *jlist; struct scif_portID portID; struct passwd *pass; char *username = NULL; char cookie[MPSS_COOKIE_SIZE]; int len; unsigned int proto; scif_epd_t lep; scif_epd_t dep; uid_t uid; int err; if ((lep = scif_open()) < 0) { mpsslog(PINFO, "Cannot open mpssd credentials SCIF listen port: %s\n", strerror(errno)); pthread_exit((void *)1); } if (scif_bind(lep, MPSSD_CRED) < 0) { mpsslog(PINFO, "Cannot bind to mpssd credentials SCIF PORT: %s\n", strerror(errno)); pthread_exit((void *)1); } if (scif_listen(lep, 16) < 0) { mpsslog(PINFO, "Set Listen on mpssd credentials SCIF PORT fail: %s\n", strerror(errno)); pthread_exit((void *)1); } while (1) { if (scif_accept(lep, &portID, &dep, SCIF_ACCEPT_SYNC)) { if (errno != EINTR) { mpsslog(PINFO, "Wait for credentials request fail: %s\n", strerror(errno)); scif_close(dep); } continue; } if ((err = scif_recv(dep, &uid, sizeof(uid), SCIF_RECV_BLOCK)) != sizeof(uid)) { mpsslog(PINFO, "Credential connect recieve error %s\n", strerror(errno)); scif_close(dep); continue; } username = NULL; while ((pass = getpwent()) != NULL) { if (uid == pass->pw_uid) { username = pass->pw_name; break; } } endpwent(); if (username == NULL) { mpsslog(PERROR, "User request unknown UID %d\n", uid); proto = CRED_FAIL_UNKNOWNUID; scif_send(dep, &proto, sizeof(proto), 0); scif_close(dep); continue; }; if (get_cookie(pass, cookie) < 0) { proto = CRED_FAIL_READCOOKIE; scif_send(dep, &proto, sizeof(proto), 0); scif_close(dep); continue; } if ((job = malloc(sizeof(struct jobs))) == NULL) { proto = CRED_FAIL_MALLOC; scif_send(dep, &proto, sizeof(proto), 0); scif_close(dep); continue; } job->jobid = nextjobid++; job->dep = dep; job->cnt = 0; len = strlen(username); while (pthread_mutex_lock(&jobs_lock) != 0); for (mic = miclist; mic != NULL; mic = mic->next) { mpssdi = (struct mpssd_info *)mic->data; if (mpssdi->send_ep != -1) { job->cnt++; proto = REQ_CREDENTIAL; if ((scif_send(mpssdi->send_ep, &proto, sizeof(proto), 0)) < 0) { if (errno == ECONNRESET) { job->cnt--; continue; } } scif_send(mpssdi->send_ep, &job->jobid, sizeof(job->jobid), 0); scif_send(mpssdi->send_ep, &len, sizeof(len), 0); scif_send(mpssdi->send_ep, username, len, 0); len = sizeof(cookie); scif_send(mpssdi->send_ep, &len, sizeof(len), 0); scif_send(mpssdi->send_ep, cookie, len, SCIF_SEND_BLOCK); } } if (job->cnt == 0) { proto = CRED_SUCCESS; scif_send(job->dep, &proto, sizeof(proto), 0); scif_close(job->dep); } else { jlist = &gjobs; while (jlist->next) jlist = jlist->next; jlist->next = job; job->next = NULL; } while (pthread_mutex_unlock(&jobs_lock) != 0); } }
// getpwent is a macro on some platforms, so we need a wrapper: struct passwd *__hsunix_getpwent(void) { return getpwent(); }
int main(int argc, char *argv[]) { int uid = atoi(argv[1]); errno = 0; struct passwd *pPwdInfo = NULL; struct passwd *pPwdEntry = NULL; FILE *fpPasswd = fopen("/etc/passwd","r"); // Opens /etc/passwd to get a list of all users if (argc == 2) { pPwdInfo = getpwuid(uid); if ((errno) == -1) { // To check if getpwuid failed perror("getpwuid failed!"); } else { if (pPwdInfo != NULL) { printf("User Name: %s\n", pPwdInfo->pw_name); printf("User Password: %s\n", pPwdInfo->pw_passwd); printf("User ID: %d\n", pPwdInfo->pw_uid); printf("Group ID: %d\n", pPwdInfo->pw_gid); printf("User Info: %s\n", pPwdInfo->pw_gecos); printf("Home Directory: %s\n", pPwdInfo->pw_dir); printf("Shell Program: %s\n", pPwdInfo->pw_shell); } else { perror("No entry found matching the given UID"); } } } else { printf("Usage userinfo <uid>\n"); } while (!feof(fpPasswd)) { pPwdEntry = getpwent(); if ( pPwdEntry->pw_gid == pPwdInfo->pw_gid){ printf("*************Users with same Group ID***********\n"); printf("User Name: %s\n", pPwdEntry->pw_name); printf("User Password: %s\n", pPwdEntry->pw_passwd); printf("User ID: %d\n", pPwdEntry->pw_uid); printf("Group ID: %d\n", pPwdEntry->pw_gid); printf("User Info: %s\n", pPwdEntry->pw_gecos); printf("Home Directory: %s\n", pPwdEntry->pw_dir); printf("Shell Program: %s\n", pPwdEntry->pw_shell); } if ( pPwdEntry->pw_gid == 0) { printf("*************Users with Group ID = 0***********\n"); printf("User Name: %s\n", pPwdEntry->pw_name); printf("User Password: %s\n", pPwdEntry->pw_passwd); printf("User ID: %d\n", pPwdEntry->pw_uid); printf("Group ID: %d\n", pPwdEntry->pw_gid); printf("User Info: %s\n", pPwdEntry->pw_gecos); printf("Home Directory: %s\n", pPwdEntry->pw_dir); printf("Shell Program: %s\n", pPwdEntry->pw_shell); } } fclose(fpPasswd); return 0; }
/* * passwd - change a user's password file information * * This command controls the password file and commands which are used * to modify it. * * The valid options are * * -d delete the password for the named account (*) * -e expire the password for the named account (*) * -f execute chfn command to interpret flags * -g execute gpasswd command to interpret flags * -i # set sp_inact to # days (*) * -k change password only if expired * -l lock the password of the named account (*) * -n # set sp_min to # days (*) * -r # change password in # repository * -s execute chsh command to interpret flags * -S show password status of named account * -u unlock the password of the named account (*) * -w # set sp_warn to # days (*) * -x # set sp_max to # days (*) * * (*) requires root permission to execute. * * All of the time fields are entered in days and converted to the * appropriate internal format. For finer resolute the chage * command must be used. */ int main (int argc, char **argv) { const struct passwd *pw; /* Password file entry for user */ #ifndef USE_PAM char *cp; /* Miscellaneous character pointing */ const struct spwd *sp; /* Shadow file entry for user */ #endif /* !USE_PAM */ (void) setlocale (LC_ALL, ""); (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); /* * The program behaves differently when executed by root than when * executed by a normal user. */ amroot = (getuid () == 0); /* * Get the program name. The program name is used as a prefix to * most error messages. */ Prog = Basename (argv[0]); sanitize_env (); OPENLOG ("passwd"); { /* * Parse the command line options. */ int option_index = 0; int c; static struct option long_options[] = { {"all", no_argument, NULL, 'a'}, {"delete", no_argument, NULL, 'd'}, {"expire", no_argument, NULL, 'e'}, {"help", no_argument, NULL, 'h'}, {"inactive", required_argument, NULL, 'i'}, {"keep-tokens", no_argument, NULL, 'k'}, {"lock", no_argument, NULL, 'l'}, {"mindays", required_argument, NULL, 'n'}, {"quiet", no_argument, NULL, 'q'}, {"root", required_argument, NULL, 'R'}, {"repository", required_argument, NULL, 'r'}, {"status", no_argument, NULL, 'S'}, {"unlock", no_argument, NULL, 'u'}, {"warndays", required_argument, NULL, 'w'}, {"maxdays", required_argument, NULL, 'x'}, {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, "adei:kln:qR:r:Suw:x:", long_options, &option_index)) != -1) { switch (c) { case 'a': aflg = true; break; case 'd': dflg = true; anyflag = true; break; case 'e': eflg = true; anyflag = true; break; case 'i': if ( (getlong (optarg, &inact) == 0) || (inact < -1)) { fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, optarg); usage (E_BAD_ARG); } iflg = true; anyflag = true; break; case 'k': /* change only if expired, like Linux-PAM passwd -k. */ kflg = true; /* ok for users */ break; case 'l': lflg = true; anyflag = true; break; case 'n': if ( (getlong (optarg, &age_min) == 0) || (age_min < -1)) { fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, optarg); usage (E_BAD_ARG); } nflg = true; anyflag = true; break; case 'q': qflg = true; /* ok for users */ break; case 'R': if ('/' != optarg[0]) { fprintf (stderr, _("%s: invalid chroot path '%s'\n"), Prog, optarg); exit (E_BAD_ARG); } newroot = optarg; if (access (newroot, F_OK) != 0) { fprintf(stderr, _("%s: chroot directory %s does not exist\n"), Prog, newroot); exit (E_BAD_ARG); } if ( chroot(newroot) != 0 ) { fprintf(stderr, _("%s: unable to chroot to directory %s\n"), Prog, newroot); exit (E_BAD_ARG); } break; case 'r': /* -r repository (files|nis|nisplus) */ /* only "files" supported for now */ if (strcmp (optarg, "files") != 0) { fprintf (stderr, _("%s: repository %s not supported\n"), Prog, optarg); exit (E_BAD_ARG); } break; case 'S': Sflg = true; /* ok for users */ break; case 'u': uflg = true; anyflag = true; break; case 'w': if ( (getlong (optarg, &warn) == 0) || (warn < -1)) { fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, optarg); usage (E_BAD_ARG); } wflg = true; anyflag = true; break; case 'x': if ( (getlong (optarg, &age_max) == 0) || (age_max < -1)) { fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, optarg); usage (E_BAD_ARG); } xflg = true; anyflag = true; break; default: usage (E_BAD_ARG); } } } /* * Now I have to get the user name. The name will be gotten from the * command line if possible. Otherwise it is figured out from the * environment. */ pw = get_my_pwent (); if (NULL == pw) { fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", (unsigned long) getuid ())); exit (E_NOPERM); } myname = xstrdup (pw->pw_name); if (optind < argc) { name = argv[optind]; } else { name = myname; } /* * Make sure that at most one username was specified. */ if (argc > (optind+1)) { usage (E_USAGE); } /* * The -a flag requires -S, no other flags, no username, and * you must be root. --marekm */ if (aflg) { if (anyflag || !Sflg || (optind < argc)) { usage (E_USAGE); } if (!amroot) { fprintf (stderr, _("%s: Permission denied.\n"), Prog); exit (E_NOPERM); } setpwent (); while ( (pw = getpwent ()) != NULL ) { print_status (pw); } endpwent (); exit (E_SUCCESS); } #if 0 /* * Allow certain users (administrators) to change passwords of * certain users. Not implemented yet. --marekm */ if (may_change_passwd (myname, name)) amroot = 1; #endif /* * If any of the flags were given, a user name must be supplied on * the command line. Only an unadorned command line doesn't require * the user's name be given. Also, -x, -n, -w, -i, -e, -d, * -l, -u may appear with each other. -S, -k must appear alone. */ /* * -S now ok for normal users (check status of my own account), and * doesn't require username. --marekm */ if (anyflag && optind >= argc) { usage (E_USAGE); } if ( (Sflg && kflg) || (anyflag && (Sflg || kflg))) { usage (E_USAGE); } if (anyflag && !amroot) { fprintf (stderr, _("%s: Permission denied.\n"), Prog); exit (E_NOPERM); } pw = xgetpwnam (name); if (NULL == pw) { fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, name); exit (E_NOPERM); } #ifdef WITH_SELINUX /* only do this check when getuid()==0 because it's a pre-condition for changing a password without entering the old one */ if ((is_selinux_enabled() > 0) && (getuid() == 0) && (check_selinux_access (name, pw->pw_uid, PASSWD__PASSWD) != 0)) { security_context_t user_context = NULL; const char *user = "******"; if (getprevcon (&user_context) == 0) { user = user_context; } SYSLOG ((LOG_ALERT, "%s is not authorized to change the password of %s", user, name)); fprintf(stderr, _("%s: %s is not authorized to change the password of %s\n"), Prog, user, name); if (NULL != user_context) { freecon (user_context); } exit (E_NOPERM); } #endif /* WITH_SELINUX */ /* * If the UID of the user does not match the current real UID, * check if I'm root. */ if (!amroot && (pw->pw_uid != getuid ())) { fprintf (stderr, _("%s: You may not view or modify password information for %s.\n"), Prog, name); SYSLOG ((LOG_WARN, "%s: can't view or modify password information for %s", Prog, name)); closelog (); exit (E_NOPERM); } if (Sflg) { print_status (pw); exit (E_SUCCESS); } #ifndef USE_PAM /* * The user name is valid, so let's get the shadow file entry. */ sp = getspnam (name); /* !USE_PAM, no need for xgetspnam */ if (NULL == sp) { sp = pwd_to_spwd (pw); } cp = sp->sp_pwdp; /* * If there are no other flags, just change the password. */ if (!anyflag) { STRFCPY (crypt_passwd, cp); /* * See if the user is permitted to change the password. * Otherwise, go ahead and set a new password. */ check_password (pw, sp); /* * Let the user know whose password is being changed. */ if (!qflg) { printf (_("Changing password for %s\n"), name); } if (new_password (pw)) { fprintf (stderr, _("The password for %s is unchanged.\n"), name); closelog (); exit (E_NOPERM); } do_update_pwd = true; do_update_age = true; } #endif /* !USE_PAM */ /* * Before going any further, raise the ulimit to prevent colliding * into a lowered ulimit, and set the real UID to root to protect * against unexpected signals. Any keyboard signals are set to be * ignored. */ pwd_init (); #ifdef USE_PAM /* * Don't set the real UID for PAM... */ if (!anyflag) { do_pam_passwd (name, qflg, kflg); exit (E_SUCCESS); } #endif /* USE_PAM */ if (setuid (0) != 0) { fputs (_("Cannot change ID to root.\n"), stderr); SYSLOG ((LOG_ERR, "can't setuid(0)")); closelog (); exit (E_NOPERM); } if (spw_file_present ()) { update_shadow (); } else { update_noshadow (); } nscd_flush_cache ("passwd"); nscd_flush_cache ("group"); SYSLOG ((LOG_INFO, "password for '%s' changed by '%s'", name, myname)); closelog (); if (!qflg) { if (!anyflag) { #ifndef USE_PAM printf (_("%s: password changed.\n"), Prog); #endif /* USE_PAM */ } else { printf (_("%s: password expiry information changed.\n"), Prog); } } return E_SUCCESS; }
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; }
// // Allocate and return the list of interfaces on this system // int32_t scap_create_userlist(scap_t* handle) { uint32_t usercnt; uint32_t grpcnt; struct passwd *p; struct group *g; // // If the list of interfaces was already allocated for this handle (for example because this is // not the first interface list block), free it // if(handle->m_userlist != NULL) { scap_free_userlist(handle->m_userlist); handle->m_userlist = NULL; } // // First pass: count the number of users and the number of groups // p = getpwent(); for(usercnt = 0; p; p = getpwent(), usercnt++); endpwent(); g = getgrent(); for(grpcnt = 0; g; g = getgrent(), grpcnt++); endgrent(); // // Memory allocations // handle->m_userlist = (scap_userlist*)malloc(sizeof(scap_userlist)); if(handle->m_userlist == NULL) { snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "userlist allocation failed(1)"); return SCAP_FAILURE; } handle->m_userlist->nusers = usercnt; handle->m_userlist->ngroups = grpcnt; handle->m_userlist->totsavelen = 0; handle->m_userlist->users = (scap_userinfo*)malloc(usercnt * sizeof(scap_userinfo)); if(handle->m_userlist->users == NULL) { snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "userlist allocation failed(2)"); free(handle->m_userlist); return SCAP_FAILURE; } handle->m_userlist->groups = (scap_groupinfo*)malloc(grpcnt * sizeof(scap_groupinfo)); if(handle->m_userlist->groups == NULL) { snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "grouplist allocation failed(2)"); free(handle->m_userlist); free(handle->m_userlist->users); return SCAP_FAILURE; } // // Second pass: copy the data // //users p = getpwent(); for(usercnt = 0; p; p = getpwent(), usercnt++) { handle->m_userlist->users[usercnt].uid = p->pw_uid; handle->m_userlist->users[usercnt].gid = p->pw_gid; strncpy(handle->m_userlist->users[usercnt].name, p->pw_name, sizeof(handle->m_userlist->users[usercnt].name)); strncpy(handle->m_userlist->users[usercnt].homedir, p->pw_dir, sizeof(handle->m_userlist->users[usercnt].homedir)); strncpy(handle->m_userlist->users[usercnt].shell, p->pw_shell, sizeof(handle->m_userlist->users[usercnt].shell)); handle->m_userlist->totsavelen += sizeof(uint8_t) + // type sizeof(uint32_t) + // uid sizeof(uint32_t) + // gid strlen(handle->m_userlist->users[usercnt].name) + 2 + strlen(handle->m_userlist->users[usercnt].homedir) + 2 + strlen(handle->m_userlist->users[usercnt].shell) + 2; } endpwent(); // groups g = getgrent(); for(grpcnt = 0; g; g = getgrent(), grpcnt++) { handle->m_userlist->groups[grpcnt].gid = g->gr_gid; strncpy(handle->m_userlist->groups[grpcnt].name, g->gr_name, sizeof(handle->m_userlist->groups[grpcnt].name)); handle->m_userlist->totsavelen += sizeof(uint8_t) + // type sizeof(uint32_t) + // gid strlen(handle->m_userlist->groups[grpcnt].name) + 2; } endgrent(); return SCAP_SUCCESS; }
static void SFgetHomeDirs (void) { struct passwd *pw; int alloc; int i; SFEntry *entries = NULL; int len; int maxChars; alloc = 1; i = 1; entries = (SFEntry *) XtMalloc (sizeof (SFEntry)); SFlogins = (SFLogin *) XtMalloc (sizeof (SFLogin)); entries[0].real = XtMalloc (3); strcpy (entries[0].real, "~"); entries[0].shown = entries[0].real; entries[0].statDone = 1; SFlogins[0].name = ""; pw = getpwuid ((int) getuid ()); SFstrdup (&SFlogins[0].dir, pw ? pw->pw_dir : "/"); maxChars = 0; setpwent (); while ((pw = getpwent ()) && (*(pw->pw_name))) { if (i >= alloc) { alloc *= 2; entries = (SFEntry *) XtRealloc ( (char *) entries, (unsigned) (alloc * sizeof (SFEntry)) ); SFlogins = (SFLogin *) XtRealloc ( (char *) SFlogins, (unsigned) (alloc * sizeof (SFLogin)) ); } len = strlen (pw->pw_name); entries[i].real = XtMalloc ((unsigned) (len + 3)); strcat (strcpy (entries[i].real, "~"), pw->pw_name); entries[i].shown = entries[i].real; entries[i].statDone = 1; if (len > maxChars) { maxChars = len; } SFstrdup (&SFlogins[i].name, pw->pw_name); SFstrdup (&SFlogins[i].dir, pw->pw_dir); i++; } SFhomeDir.dir = XtMalloc (1); SFhomeDir.dir[0] = 0; SFhomeDir.path = SFcurrentPath; SFhomeDir.entries = entries; SFhomeDir.nEntries = i; SFhomeDir.vOrigin = 0; /* :-) */ SFhomeDir.nChars = maxChars + 2; SFhomeDir.hOrigin = 0; SFhomeDir.changed = 1; SFhomeDir.beginSelection = -1; SFhomeDir.endSelection = -1; #if defined (SVR4) || defined (SYSV) || defined (USG) qsort ((char *) entries, (unsigned)i, sizeof (SFEntry), SFcompareEntries); qsort ((char *) SFlogins, (unsigned)i, sizeof (SFLogin), SFcompareLogins); #else /* defined (SVR4) || defined (SYSV) || defined (USG) */ qsort ((char *) entries, i, sizeof (SFEntry), SFcompareEntries); qsort ((char *) SFlogins, i, sizeof (SFLogin), SFcompareLogins); #endif /* defined (SVR4) || defined (SYSV) || defined (USG) */ for (i--; i >= 0; i--) { strcat (entries[i].real, "/"); } }
//------------------------------------------------------------------------------ // FUNCTION: checkAccess // // REMARKS: Status of context user // // PARAMETERS: [IN] filename -> file name to verify access // [IN] chkoper -> valid options: SEC_OPT_READ, // SEC_OPT_WRITE, // SEC_OPT_READ_WRITE or // SEC_OPT_EXECUTE // // RETURN: TRUE, if user have privileges, otherwise FALSE //------------------------------------------------------------------------------ Boolean NTPProviderSecurity::checkAccess(const String filename, const String chkoper) { FILE *fp; struct passwd *pwd; struct group *grp; struct stat st; int ps, opt, i, j, ct = 0, ngr = 0; ushort rt, gr, ot, trt, tgr; Boolean ok = false, isRoot = false, okUser = (secUsername.size() > 0); char buffer[500]; char *member; // Groups array Array<gid_t> grps; // store user id uid_t user_id = -1; // store group id - is there only one group id? gid_t group_id; int accessrights; String strTmp; String path; String strValue; Array<String> strCmd; Array<String> strMembers; if(okUser) { // Retrieve uid from user strValue.clear(); // Go through password entries and find the entry that matches "secUsername" pwd = getpwent(); if(pwd != NULL) { strValue.assign(pwd->pw_name); while(!String::equalNoCase(strValue, secUsername)) { pwd = getpwent(); if(pwd == NULL) break; strValue.assign(pwd->pw_name); } } // indicate that the processing of the password database is complete endpwent(); // If we didn't find the entry - just return if(strValue.size() == 0 || !String::equalNoCase(strValue, secUsername)) return ok; // DLH set the group and user id user_id = pwd->pw_uid; group_id = pwd->pw_gid; grps.clear(); isRoot = (user_id == 0); if(!isRoot) { grps.append(group_id); // Find the groups to which this user belongs and store the list in "member" strValue.clear(); // Return a pointer to the first group structure in the group database grp = getgrent(); while(grp) { i = 0; strMembers.clear(); member = grp->gr_mem[i++]; while (member) { strMembers.append(member); member = grp->gr_mem[i++]; } for(i=0; i < strMembers.size(); i++) { strValue.assign(strMembers[i]); ps = strValue.find(secUsername); if(ps >= 0) { grps.append(grp->gr_gid); break; } } // Get the next group structure grp = getgrent(); } // Indicate that the processing of the group database is complete endgrent(); } } // Build the command with path of file strCmd.clear(); ps = filename.reverseFind('/'); if(ps > 0) { path.assign(filename.subString(0, ps)); strCmd.append(path); } // Build the command to retrieve user informations strCmd.append(filename); // // Identify the type test // opt = 0; if(String::equalNoCase(chkoper, SEC_OPT_READ) || String::equalNoCase(chkoper, SEC_OPT_READ_WRITE)) opt = 1; else if(String::equalNoCase(chkoper, SEC_OPT_WRITE) || String::equalNoCase(chkoper, SEC_OPT_READ_WRITE)) opt = 2; else if(String::equalNoCase(chkoper, SEC_OPT_EXECUTE) || String::equalNoCase(chkoper, SEC_OPT_ALL)) opt = 3; // Verify permissions from directory and file name for(int i=0; i<strCmd.size(); i++) { ok = false; strTmp.assign(strCmd[i]); // The stat call gets information about the file access permissions if(stat(strTmp.getCString(), &st) == -1) return ok; // Return ok, if is invalid user_id and other permission or is root if(!okUser && st.st_basemode & 0x04 || isRoot) ok = true; else if(user_id > 0) { // Use getaccess to check permission instead of stat so that we get consistent response from OS accessrights = getaccess( strTmp.getCString(), user_id, grps.size(), grps.getData(),(void *) 0,(void *) 0); if ( accessrights == -1) // if error - just return with ok set to false return ok; // Verify status by type test switch(opt) { case 1: ok = (accessrights & R_OK); break; case 2: ok = (accessrights & W_OK); break; case 3: ok = (accessrights & X_OK); break; default: break; } } if(!ok) break; } return ok; }
static void userlist(int argc, char **argv) { PERSON *pn; DBT data, key; struct utmpx *user; struct passwd *pw; int r, sflag1, *used, *ip; char **ap, **nargv, **np, **p; FILE *conf_fp; char conf_alias[LINE_MAX]; char *conf_realname; int conf_length; if ((nargv = malloc((argc+1) * sizeof(char *))) == NULL || (used = calloc(argc, sizeof(int))) == NULL) err(1, NULL); /* Pull out all network requests. */ for (ap = p = argv, np = nargv; *p; ++p) if (strchr(*p, '@')) *np++ = *p; else *ap++ = *p; *np++ = NULL; *ap++ = NULL; if (!*argv) goto net; /* * Mark any arguments beginning with '/' as invalid so that we * don't accidentally confuse them with expansions from finger.conf */ for (p = argv, ip = used; *p; ++p, ++ip) if (**p == '/') { *ip = 1; warnx("%s: no such user", *p); } /* * Traverse the finger alias configuration file of the form * alias:(user|alias), ignoring comment lines beginning '#'. */ if ((conf_fp = fopen(_PATH_FINGERCONF, "r")) != NULL) { while(fgets(conf_alias, sizeof(conf_alias), conf_fp) != NULL) { conf_length = strlen(conf_alias); if (*conf_alias == '#' || conf_alias[--conf_length] != '\n') continue; conf_alias[conf_length] = '\0'; /* Remove trailing LF */ if ((conf_realname = strchr(conf_alias, ':')) == NULL) continue; *conf_realname = '\0'; /* Replace : with NUL */ for (p = argv; *p; ++p) { if (strcmp(*p, conf_alias) == 0) { if ((*p = strdup(conf_realname+1)) == NULL) { err(1, NULL); } } } } (void)fclose(conf_fp); } /* * Traverse the list of possible login names and check the login name * and real name against the name specified by the user. If the name * begins with a '/', try to read the file of that name instead of * gathering the traditional finger information. */ if (mflag) for (p = argv, ip = used; *p; ++p, ++ip) { if (**p != '/' || *ip == 1 || !show_text("", *p, "")) { if (((pw = getpwnam(*p)) != NULL) && !hide(pw)) enter_person(pw); else if (!*ip) warnx("%s: no such user", *p); } } else { while ((pw = getpwent()) != NULL) { for (p = argv, ip = used; *p; ++p, ++ip) if (**p == '/' && *ip != 1 && show_text("", *p, "")) *ip = 1; else if (match(pw, *p) && !hide(pw)) { enter_person(pw); *ip = 1; } } for (p = argv, ip = used; *p; ++p, ++ip) if (!*ip) warnx("%s: no such user", *p); } /* Handle network requests. */ net: for (p = nargv; *p;) { netfinger(*p++); if (*p || entries) printf("\n"); } free(used); if (entries == 0) return; if (kflag) return; /* * Scan thru the list of users currently logged in, saving * appropriate data whenever a match occurs. */ setutxent(); while ((user = getutxent()) != NULL) { if (user->ut_type != USER_PROCESS) continue; if ((pn = find_person(user->ut_user)) == NULL) continue; enter_where(user, pn); } endutxent(); if (db) for (sflag1 = R_FIRST;; sflag1 = R_NEXT) { PERSON *tmp; r = (*db->seq)(db, &key, &data, sflag1); if (r == -1) err(1, "db seq"); if (r == 1) break; memmove(&tmp, data.data, sizeof tmp); enter_lastlog(tmp); } }
int main(int argc, char *argv[]) { int f_dayAfter = 0; /* days after current date */ int f_dayBefore = 0; /* days before current date */ int Friday = 5; /* day before weekend */ int ch; struct tm tp1, tp2; (void)setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:l:t:U:W:?")) != -1) switch (ch) { case '-': /* backward contemptible */ case 'a': if (getuid()) { errno = EPERM; err(1, NULL); } doall = 1; break; case 'W': /* we don't need no steenking Fridays */ Friday = -1; /* FALLTHROUGH */ case 'A': /* days after current date */ f_dayAfter = atoi(optarg); if (f_dayAfter < 0) errx(1, "number of days must be positive"); break; case 'B': /* days before current date */ f_dayBefore = atoi(optarg); if (f_dayBefore < 0) errx(1, "number of days must be positive"); break; case 'D': /* debug output of sun and moon info */ DEBUG = optarg; break; case 'd': /* debug output of current date */ debug = 1; break; case 'F': /* Change the time: When does weekend start? */ Friday = atoi(optarg); break; case 'f': /* other calendar file */ calendarFile = optarg; break; case 'l': /* Change longitudal position */ EastLongitude = strtol(optarg, NULL, 10); break; case 't': /* other date, for tests */ f_time = Mktime(optarg); break; case 'U': /* Change UTC offset */ UTCOffset = strtod(optarg, NULL); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc) usage(); /* use current time */ if (f_time <= 0) (void)time(&f_time); /* if not set, determine where I could be */ { if (UTCOffset == UTCOFFSET_NOTSET && EastLongitude == LONGITUDE_NOTSET) { /* Calculate on difference between here and UTC */ time_t t; struct tm tm; long utcoffset, hh, mm, ss; double uo; time(&t); localtime_r(&t, &tm); utcoffset = tm.tm_gmtoff; /* seconds -> hh:mm:ss */ hh = utcoffset / SECSPERHOUR; utcoffset %= SECSPERHOUR; mm = utcoffset / SECSPERMINUTE; utcoffset %= SECSPERMINUTE; ss = utcoffset; /* hh:mm:ss -> hh.mmss */ uo = mm + (100.0 * (ss / 60.0)); uo /= 60.0 / 100.0; uo = hh + uo / 100; UTCOffset = uo; EastLongitude = UTCOffset * 15; } else if (UTCOffset == UTCOFFSET_NOTSET) { /* Base on information given */ UTCOffset = EastLongitude / 15; } else if (EastLongitude == LONGITUDE_NOTSET) { /* Base on information given */ EastLongitude = UTCOffset * 15; } } settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2); generatedates(&tp1, &tp2); /* * FROM now on, we are working in UTC. * This will only affect moon and sun related events anyway. */ if (setenv("TZ", "UTC", 1) != 0) errx(1, "setenv: %s", strerror(errno)); tzset(); if (debug) dumpdates(); if (DEBUG != NULL) { dodebug(DEBUG); exit(0); } if (doall) while ((pw = getpwent()) != NULL) { (void)setegid(pw->pw_gid); (void)initgroups(pw->pw_name, pw->pw_gid); (void)seteuid(pw->pw_uid); if (!chdir(pw->pw_dir)) cal(); (void)seteuid(0); } else cal(); exit(0); }
int main(int argc, char **argv) { struct passwd *pwd; int arg; int errors = 0; /* * Get my name so that I can use it to report errors. */ Prog = Basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); #ifdef SHADOWPWD is_shadow_pwd = spw_file_present(); #endif #ifdef SHADOWGRP is_shadow_grp = sgr_file_present(); #endif /* * The open routines for the DBM files don't use read-write * as the mode, so we have to clue them in. */ #ifdef NDBM pw_dbm_mode = O_RDWR; #ifdef SHADOWPWD sp_dbm_mode = O_RDWR; #endif gr_dbm_mode = O_RDWR; #ifdef SHADOWGRP sg_dbm_mode = O_RDWR; #endif #endif while ((arg = getopt (argc, argv, "fr")) != EOF) { switch (arg) { case 'f': /* force remove even if not owned by user */ fflg++; break; case 'r': /* remove home dir and mailbox */ rflg++; break; default: usage(); } } if (optind + 1 != argc) usage (); /* * Start with a quick check to see if the user exists. */ user_name = argv[argc - 1]; if (! (pwd = getpwnam (user_name))) { fprintf(stderr, _("%s: user %s does not exist\n"), Prog, user_name); exit(E_NOTFOUND); } #ifdef USE_NIS /* * Now make sure it isn't an NIS user. */ if (__ispwNIS ()) { char *nis_domain; char *nis_master; fprintf(stderr, _("%s: user %s is a NIS user\n"), Prog, user_name); if (! yp_get_default_domain (&nis_domain) && ! yp_master (nis_domain, "passwd.byname", &nis_master)) { fprintf(stderr, _("%s: %s is the NIS master\n"), Prog, nis_master); } exit(E_NOTFOUND); } #endif user_id = pwd->pw_uid; user_home = xstrdup(pwd->pw_dir); /* * Check to make certain the user isn't logged in. */ user_busy (user_name, user_id); /* * Do the hard stuff - open the files, create the user entries, * create the home directory, then close and update the files. */ open_files (); update_user (); update_groups (); #ifndef NO_REMOVE_MAILBOX if (rflg) remove_mailbox(); #endif if (rflg && !fflg && !is_owner(user_id, user_home)) { fprintf(stderr, _("%s: %s not owned by %s, not removing\n"), Prog, user_home, user_name); rflg = 0; errors++; } /* This may be slow, the above should be good enough. */ #ifdef EXTRA_CHECK_HOME_DIR if (rflg && !fflg) { /* * For safety, refuse to remove the home directory * if it would result in removing some other user's * home directory. Still not perfect so be careful, * but should prevent accidents if someone has /home * or / as home directory... --marekm */ setpwent(); while ((pwd = getpwent())) { if (strcmp(pwd->pw_name, user_name) == 0) continue; if (path_prefix(user_home, pwd->pw_dir)) { fprintf(stderr, _("%s: not removing directory %s (would remove home of user %s)\n"), Prog, user_home, pwd->pw_name); rflg = 0; errors++; break; } } } #endif if (rflg) { if (remove_tree(user_home) || rmdir(user_home)) { fprintf(stderr, _("%s: error removing directory %s\n"), Prog, user_home); errors++; } } /* * Cancel any crontabs or at jobs. Have to do this before we * remove the entry from /etc/passwd. */ user_cancel(user_name); close_files (); exit(errors ? E_HOMEDIR : E_SUCCESS); /*NOTREACHED*/ }
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); }
/*....................................................................... * The _hd_scan_user_home_dirs() function calls a user-provided function * for each username known by the system, passing the function both * the name and the home directory of the user. * * Input: * home HomeDir * The resource object for reading home * directories. * prefix const char * Only information for usernames that * start with this prefix will be * returned. Note that the empty & string "", matches all usernames. * data void * Anonymous data to be passed to the * callback function. * callback_fn HOME_DIR_FN(*) The function to call for each user. * Output: * return int 0 - Successful completion. * 1 - An error occurred. A description * of the error can be obtained by * calling _hd_last_home_dir_error(). */ int _hd_scan_user_home_dirs(HomeDir *home, const char *prefix, void *data, HOME_DIR_FN(*callback_fn)) { int waserr = 0; /* True after errors */ int prefix_len; /* The length of prefix[] */ /* * Check the arguments. */ if(!home || !prefix || !callback_fn) { if(home) { _err_record_msg(home->err, "_hd_scan_user_home_dirs: Missing callback function", END_ERR_MSG); }; return 1; }; /* * Get the length of the username prefix. */ prefix_len = strlen(prefix); /* * There are no reentrant versions of getpwent() etc for scanning * the password file, so disable username completion when the * library is compiled to be reentrant. */ #if defined(PREFER_REENTRANT) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L #if defined __sun && defined __SVR4 if(0) #else if(1) #endif { struct passwd pwd_buffer; /* A returned password entry */ struct passwd *pwd; /* A pointer to pwd_buffer */ char buffer[512]; /* The buffer in which the string members of */ /* pwd_buffer are stored. */ /* * See if the prefix that is being completed is a complete username. */ if(!waserr && getpwnam_r(prefix, &pwd_buffer, buffer, sizeof(buffer), &pwd) == 0 && pwd != NULL) { waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir, _err_get_msg(home->err), ERR_MSG_LEN); }; /* * See if the username of the current user minimally matches the prefix. */ if(!waserr && getpwuid_r(getuid(), &pwd_buffer, buffer, sizeof(buffer), &pwd) == 0 && pwd != NULL && strncmp(prefix, pwd->pw_name, prefix_len)==0) { waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir, _err_get_msg(home->err), ERR_MSG_LEN); }; /* * Reentrancy not required? */ } else #endif { struct passwd pwd_buffer; /* A returned password entry */ struct passwd *pwd; /* The pointer to the latest password entry */ /* * Open the password file. */ setpwent(); /* * Read the contents of the password file, looking for usernames * that start with the specified prefix, and adding them to the * list of matches. */ #if defined __sun && defined __SVR4 while((pwd = getpwent_r(&pwd_buffer, home->buffer, home->buflen)) != NULL && !waserr) { #else while((pwd = getpwent()) != NULL && !waserr) { #endif if(strncmp(prefix, pwd->pw_name, prefix_len) == 0) { waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir, _err_get_msg(home->err), ERR_MSG_LEN); }; }; /* * Close the password file. */ endpwent(); }; /* * Under ksh ~+ stands for the absolute pathname of the current working * directory. */ if(!waserr && strncmp(prefix, "+", prefix_len) == 0) { const char *pwd = hd_getpwd(home); if(pwd) { waserr = callback_fn(data, "+", pwd, _err_get_msg(home->err),ERR_MSG_LEN); } else { waserr = 1; _err_record_msg(home->err, "Can't determine current directory.", END_ERR_MSG); }; }; return waserr; } /*....................................................................... * Return the value of getenv("PWD") if this points to the current * directory, or the return value of getcwd() otherwise. The reason for * prefering PWD over getcwd() is that the former preserves the history * of symbolic links that have been traversed to reach the current * directory. This function is designed to provide the equivalent * expansion of the ksh ~+ directive, which normally returns its value * of PWD. * * Input: * home HomeDir * The resource object for reading home directories. * Output: * return const char * A pointer to either home->buffer, where the * pathname is recorded, the string returned by * getenv("PWD"), or NULL on error. */ static const char *hd_getpwd(HomeDir *home) { /* * Get the absolute path of the current working directory. */ char *cwd = getcwd(home->buffer, home->buflen); /* * Some shells set PWD with the path of the current working directory. * This will differ from cwd in that it won't have had symbolic links * expanded. */ const char *pwd = getenv("PWD"); /* * If PWD was set, and it points to the same directory as cwd, return * its value. Note that it won't be the same if the current shell or * the current program has changed directories, after inheriting PWD * from a parent shell. */ struct stat cwdstat, pwdstat; if(pwd && cwd && stat(cwd, &cwdstat)==0 && stat(pwd, &pwdstat)==0 && cwdstat.st_dev == pwdstat.st_dev && cwdstat.st_ino == pwdstat.st_ino) return pwd; /* * Also return pwd if getcwd() failed, since it represents the best * information that we have access to. */ if(!cwd) return pwd; /* * In the absence of a valid PWD, return cwd. */ return cwd; }
void main() { char foo[64]; char uname[9],person[32],passwd[9],dir[32],shell[32],salt[3]; unsigned int group,uid; int bad=0,i,correct=0; time_t tm; struct passwd *pw; FILE *passwd_file; /* Yep, it's a file allright */ unused_uid = FIRST; if (getuid()!=0) { printf("You don't have access to add a new user.\n"); printf("Only root can add new users to the system.\n"); exit(1); } if ((bull=fopen("/etc/shadow","r"))!=NULL) found_shadow(); if ((bull=fopen("/etc/passwd","r"))==NULL) { printf("Fatal error: password file not found.\n"); exit(1); } while (!correct) { /* loop until a "good" uname is chosen */ getlogin: printf("\nLogin to add (^C to quit): "); fflush(stdout); gets(uname); if (strlen(uname)>8) { printf("The login name must be maximum 8 characters long.\n"); goto getlogin; } for (i=0;i<strlen(uname);i++) { if (!(((uname[i]>='A') && (uname[i]<='Z')) || ((uname[i]>='a') && (uname[i]<='z')) || ((uname[i]>='0') && (uname[i]<='9')))) { printf("Invalid character in login.\n"); goto getlogin; } } if (nag=getpwnam(uname) != NULL) { printf("Login in use. Choose another one.\n"); goto getlogin; } putchar('\n'); unused_uid = find_unused(++unused_uid); printf("\nEditing information for new user [%s]:\n",uname); printf("\nFull name: "); fflush(stdout); gets(person); printf("GID [%d]: ",DEFAULT_GROUP); fflush(stdout); gets(foo); group=atoi(foo); if (group==0) group=DEFAULT_GROUP; printf("UID [%d]: ",unused_uid); fflush(stdout); gets(foo); uid=atoi(foo); if (uid==0) uid=unused_uid; if ((pw=getpwuid(uid))!=NULL) { printf("\nWarning: UID [%d] already in use, this would conflict with\n",uid); printf("who already owns this user ID. [%s]'s UID has been reset to\n",uname); printf("the last unused UID: [%d].\n",unused_uid); uid=unused_uid; } fflush(stdin); printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname); fflush(stdout); gets(dir); if (!strcmp(dir,"")) sprintf(dir,"%s/%s",DEFAULT_HOME,uname); fflush(stdin); printf("Shell [%s]: ",DEFAULT_SHELL); fflush(stdout); gets(shell); if (!strcmp(shell,"")) sprintf(shell,"%s",DEFAULT_SHELL); fflush(stdin); printf("Password [%s]: ",uname); fflush(stdout); gets(passwd); if (!strcmp(passwd,"")) sprintf(passwd,"%s",uname); time(&tm); salt[0]=(tm.t_time & 0x0f)+'A'; salt[1]=((tm.t_time & 0xf0) >> 4)+'a'; salt[2]=0; printf("\nInformation for new user [%s]:\n",uname); printf("Home directory: [%s]\nShell: [%s]\n",dir,shell); printf("Password: [%s]\nUID: [%d]\nGID: [%d]\n",passwd,uid,group); printf("\nIs this correct? [y/N]: "); fflush(stdout); fflush(stdin); gets(foo); bad=correct=(foo[0]=='y'||foo[0]=='Y'); if (bad!=1) printf("\nUser [%s] not added.\n",uname); } printf("\nAdding login [%s]...\n",uname); strcpy(foo,PASSWD_FILE); strcat(foo,".old"); if ((passwd_file=fopen(foo,"w")) == NULL) { printf("Error creating password backup file.\n"); exit(1); } setpwent(); for (i=0;(pw=getpwent())!=NULL;++i) { if (putpwent(pw,passwd_file)==-1) { printf("Error writing password backup file.\n"); exit(1); } } endpwent(); fclose(passwd_file); if (i<1) printf("Can't backup password file.\n"); passwd_file=fopen(PASSWD_FILE,"a"); fprintf(passwd_file,"%s:%s:%d:%d:%s:%s:%s\n" ,uname,crypt(passwd,salt),uid,group,person,dir,shell); fflush(passwd_file); fclose(passwd_file); printf("Making directory [%s]...\n",dir); mkdir(dir,DEFAULT_PERMS); chown(dir,uid,group); printf("Done.\n"); }
int main(int argc, char *argv[]) { char *tmp; struct passwd *mypasswd; pid_t pid; atexit(my_exit_1); atexit(my_exit_2); if ((pid = fork()) < 0) { fprintf(stderr, "fork error!\n"); } else if (pid == 0) { fprintf(stdout, "print from child\n"); } else { sleep(2); fprintf(stdout, "waiting for child to finish\n"); sleep(2); waitpid(pid, NULL, 0); fprintf(stdout, "print from parent\n"); // sleep(10); } setpwent(); while ((mypasswd = getpwent()) != NULL) { printf("name: %s\n", mypasswd->pw_name); printf("passwd: %s\n", mypasswd->pw_passwd); printf("uid: %d\tgid: %d\n", mypasswd->pw_uid, mypasswd->pw_gid); printf("home dir: %s\n", mypasswd->pw_dir); printf("shell: %s\n\n", mypasswd->pw_shell); } tmp = getenv("HOME"); if (!tmp) printf("HOME not export\n"); else printf("HOME: %s\n", tmp); tmp = getenv("HOME"); if (!tmp) printf("srcs not export\n"); else printf("srcs: %s\n", tmp); sprintf(tmp, "/home"); printf("tmp:%s\n", tmp); if((setenv("HOME", tmp, 1)) == -1) printf("set srcs error\n"); else printf("set srcs ok\n"); tmp = getenv("HOME"); if (!tmp) printf("srcs not export\n"); else printf("srcs: %s\n", tmp); printf("parent pid: %d\n", getppid()); printf("pid : %d\n", getpid()); printf("%0x\n", NOSIGHT); // _exit(0); exit(0); }
int main(void) { int fd; struct stat stat_buf; struct passwd *pw; uid_t old_uid; gid_t old_gid; umask(0); fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (fd == -1) { perror("An error occurs when calling shm_open()"); return PTS_UNRESOLVED; } if (ftruncate(fd, BUF_SIZE) != 0) { perror("An error occurs when calling ftruncate()"); shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } if (fstat(fd, &stat_buf) != 0) { perror("An error occurs when calling fstat()"); shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } old_uid = stat_buf.st_uid; old_gid = stat_buf.st_gid; /* search for the first user which is non root and which is not the current user */ while ((pw = getpwent()) != NULL) if (strcmp(pw->pw_name, "root") && pw->pw_uid != getuid()) break; if (pw == NULL) { printf("There is no other user than current and root.\n"); shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } if (seteuid(pw->pw_uid) != 0) { if (errno == EPERM) { printf ("You don't have permission to change your UID.\nTry to rerun this test as root.\n"); } else { perror("An error occurs when calling seteuid()"); } shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } printf("Testing with user '%s' (uid: %i)\n", pw->pw_name, pw->pw_uid); fd = shm_open(SHM_NAME, O_RDWR | O_TRUNC, 0); if (fd == -1) { perror("An error occurs when calling shm_open()"); seteuid(getuid()); shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } if (fstat(fd, &stat_buf) != 0) { perror("An error occurs when calling fstat()"); seteuid(getuid()); shm_unlink(SHM_NAME); return PTS_UNRESOLVED; } seteuid(getuid()); shm_unlink(SHM_NAME); if (stat_buf.st_uid == old_uid && stat_buf.st_gid == old_gid) { printf("Test PASSED\n"); return PTS_PASS; } if (stat_buf.st_uid != old_uid) printf("The user ID has changed.\n"); if (stat_buf.st_gid != old_gid) printf("The group ID has changed.\n"); return PTS_FAIL; }
struct passwd *sys_getpwent(void) { return getpwent(); }
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 WDialog * init_chown (void) { int lines, cols; int i; int y; struct passwd *l_pass; struct group *l_grp; WDialog *ch_dlg; do_refresh (); end_chown = need_update = current_file = 0; single_set = (current_panel->marked < 2) ? 3 : 0; cols = GW * 3 + 2 + 6; lines = GH + 4 + (single_set ? 2 : 4); ch_dlg = dlg_create (TRUE, 0, 0, lines, cols, dialog_colors, chown_callback, NULL, "[Chown]", _("Chown command"), DLG_CENTER); add_widget (ch_dlg, groupbox_new (2, 3, GH, GW, _("User name"))); l_user = listbox_new (3, 4, GH - 2, GW - 2, FALSE, NULL); add_widget (ch_dlg, l_user); /* add field for unknown names (numbers) */ listbox_add_item (l_user, LISTBOX_APPEND_AT_END, 0, _("<Unknown user>"), 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 (); add_widget (ch_dlg, groupbox_new (2, 4 + GW, GH, GW, _("Group name"))); l_group = listbox_new (3, 5 + GW, GH - 2, GW - 2, FALSE, NULL); add_widget (ch_dlg, l_group); /* add field for unknown names (numbers) */ listbox_add_item (l_group, LISTBOX_APPEND_AT_END, 0, _("<Unknown group>"), NULL); /* 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 (2, 5 + GW * 2, GH, GW, _("File"))); /* add widgets for the file information */ for (i = 0; i < LABELS; i++) { chown_label[i].l = label_new (chown_label[i].y, 7 + GW * 2, ""); add_widget (ch_dlg, chown_label[i].l); } if (!single_set) { int x; add_widget (ch_dlg, hline_new (lines - chown_but[0].y - 1, -1, -1)); y = lines - chown_but[0].y; x = (cols - blen) / 2; for (i = 0; i < BUTTONS - 2; i++) { add_widget (ch_dlg, button_new (y, x, chown_but[i].ret_cmd, chown_but[i].flags, chown_but[i].text, NULL)); x += chown_but[i].len + 1; } } i = BUTTONS - 2; y = lines - chown_but[i].y; add_widget (ch_dlg, hline_new (y - 1, -1, -1)); add_widget (ch_dlg, button_new (y, WIDGET (ch_dlg)->cols / 2 - chown_but[i].len, chown_but[i].ret_cmd, chown_but[i].flags, chown_but[i].text, NULL)); i++; add_widget (ch_dlg, button_new (y, WIDGET (ch_dlg)->cols / 2 + 1, chown_but[i].ret_cmd, chown_but[i].flags, chown_but[i].text, NULL)); /* select first listbox */ dlg_select_widget (l_user); return ch_dlg; }