static struct spwd * getspnam_a (const char *name) { int err; long bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); struct spwd *ret = NULL; struct spwd *buf; if (bufsize <= 0) bufsize = 8192; buf = malloc (sizeof(struct spwd) + bufsize); if (buf == NULL) { errno = ENOMEM; return NULL; } err = getspnam_r (name, buf, (char *)(buf + 1), bufsize, &ret); if (ret == NULL) { free (buf); if (err == 0) err = ENOENT; errno = err; } return ret; }
int checkpasswd(char *user, char *pass) { #if defined(FREEBSD) || defined(__linux__) || defined(MACOSX) struct passwd *pwd; #elif SOLARIS struct spwd *spwd, sp; char buf[512]; #endif int matched = 0; if (user == NULL) { /* user must be specified */ return(-1); } #if defined(FREEBSD) || defined(__linux__) || defined(MACOSX) setreuid(PROCUID, 0); pwd = getpwnam(user); setreuid(0, PROCUID); if (pwd == NULL) { /* error in getpwnam */ return(-1); } if (pwd->pw_passwd == NULL && pass == NULL) { /* null password matched */ return(0); } if (*pwd->pw_passwd) { if (strcmp(pwd->pw_passwd, crypt(pass, pwd->pw_passwd)) == 0) { matched = 1; } } memset(pwd->pw_passwd, 0, strlen(pwd->pw_passwd)); #elif SOLARIS setreuid(PROCUID, 0); spwd = getspnam_r(user, &sp, buf, sizeof buf); setreuid(0, PROCUID); if (spwd == NULL) { /* error in getspnam */ return(-1); } if (spwd->sp_pwdp == NULL && pass == NULL) { /* null password matched */ return(0); } if (*spwd->sp_pwdp) { if (strcmp(spwd->sp_pwdp, crypt(pass, spwd->sp_pwdp)) == 0) { matched = 1; } } memset(spwd->sp_pwdp, 0, strlen(spwd->sp_pwdp)); #endif if (matched) { return(0); } else { return(-1); } }
int correct_password(const struct passwd *pw) { char *unencrypted, *encrypted; const char *correct; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ struct spwd spw; struct spwd *result; char buffer[256]; #endif correct = pw->pw_passwd; #if ENABLE_FEATURE_SHADOWPASSWDS if (LONE_CHAR(pw->pw_passwd, 'x') || LONE_CHAR(pw->pw_passwd, '*')) { if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) bb_error_msg("no valid shadow password, checking ordinary one"); else correct = spw.sp_pwdp; } #endif if (!correct || correct[0] == '\0') return 1; unencrypted = bb_askpass(0, "Password: "); if (!unencrypted) { return 0; } encrypted = crypt(unencrypted, correct); memset(unencrypted, 0, strlen(unencrypted)); return strcmp(encrypted, correct) == 0; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* be reentrant */ struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); int fCorrect = !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); if (!fCorrect) return VERR_PERMISSION_DENIED; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_PERMISSION_DENIED; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_PERMISSION_DENIED; #endif }
struct spwd * getspnam(const char *nam) { nss_XbyY_buf_t *b = get_spbuf(); return (b == NULL ? NULL : getspnam_r(nam, b->result, b->buffer, b->buflen)); }
int correct_password(const struct passwd *pw) { char *unencrypted, *encrypted; const char *correct; int r; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ struct spwd spw; char buffer[256]; #endif /* fake salt. crypt() can choke otherwise. */ correct = "aa"; if (!pw) { /* "aa" will never match */ goto fake_it; } correct = pw->pw_passwd; #if ENABLE_FEATURE_SHADOWPASSWDS if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) { /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result); correct = (r || !result) ? "aa" : result->sp_pwdp; } #endif if (!correct[0]) /* empty password field? */ return 1; fake_it: unencrypted = bb_askpass(0, "Password: "); if (!unencrypted) { return 0; } encrypted = pw_encrypt(unencrypted, correct, 1); r = (strcmp(encrypted, correct) == 0); free(encrypted); memset(unencrypted, 0, strlen(unencrypted)); return r; }
static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZE]) { const char *pass; if (!pw) return "aa"; /* "aa" will never match */ pass = pw->pw_passwd; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) { struct spwd spw; int r; /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; r = getspnam_r(pw->pw_name, &spw, buffer, SHADOW_BUFSIZE, &result); pass = (r || !result) ? "aa" : result->sp_pwdp; } #endif return pass; }
int sulogin_main(int argc, char **argv) { char *cp; int timeout = 0; char *timeout_arg; struct passwd *pwd; const char *shell; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ char buffer[256]; struct spwd spw; #endif logmode = LOGMODE_BOTH; openlog(applet_name, 0, LOG_AUTH); if (getopt32(argv, "t:", &timeout_arg)) { timeout = xatoi_u(timeout_arg); } if (argv[optind]) { close(0); close(1); dup(xopen(argv[optind], O_RDWR)); close(2); dup(0); } if (!isatty(0) || !isatty(1) || !isatty(2)) { logmode = LOGMODE_SYSLOG; bb_error_msg_and_die("not a tty"); } /* Clear dangerous stuff, set PATH */ sanitize_env_for_suid(); // bb_askpass() already handles this // signal(SIGALRM, catchalarm); pwd = getpwuid(0); if (!pwd) { goto auth_error; } #if ENABLE_FEATURE_SHADOWPASSWDS { /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result); if (r || !result) { goto auth_error; } pwd->pw_passwd = result->sp_pwdp; } #endif while (1) { /* cp points to a static buffer that is zeroed every time */ cp = bb_askpass(timeout, "Give root password for system maintenance\n" "(or type Control-D for normal startup):"); if (!cp || !*cp) { bb_info_msg("Normal startup"); return 0; } if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) { break; } bb_do_delay(FAIL_DELAY); bb_error_msg("login incorrect"); } memset(cp, 0, strlen(cp)); // signal(SIGALRM, SIG_DFL); bb_info_msg("System Maintenance Mode"); USE_SELINUX(renew_current_security_context()); shell = getenv("SUSHELL"); if (!shell) shell = getenv("sushell"); if (!shell) { shell = "/bin/sh"; if (pwd->pw_shell[0]) shell = pwd->pw_shell; } /* Exec login shell with no additional parameters. Never returns. */ run_shell(shell, 1, NULL, NULL); auth_error: bb_error_msg_and_die("no password entry for root"); }
struct spwd *getspnam(const char* name) { struct spwd *tmp; getspnam_r(name,&__shadow_pw,__shadow_buf,sizeof(__shadow_buf),&tmp); return tmp; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
int sulogin_main(int argc UNUSED_PARAM, char **argv) { char *cp; int timeout = 0; struct passwd *pwd; const char *shell; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ char buffer[256]; struct spwd spw; #endif logmode = LOGMODE_BOTH; openlog(applet_name, 0, LOG_AUTH); opt_complementary = "t+"; /* -t N */ getopt32(argv, "t:", &timeout); argv += optind; if (argv[0]) { close(0); close(1); dup(xopen(argv[0], O_RDWR)); close(2); dup(0); } /* Malicious use like "sulogin /dev/sda"? */ if (!isatty(0) || !isatty(1) || !isatty(2)) { logmode = LOGMODE_SYSLOG; bb_error_msg_and_die("not a tty"); } /* Clear dangerous stuff, set PATH */ sanitize_env_if_suid(); pwd = getpwuid(0); if (!pwd) { goto auth_error; } #if ENABLE_FEATURE_SHADOWPASSWDS { /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result); if (r || !result) { goto auth_error; } pwd->pw_passwd = result->sp_pwdp; } #endif while (1) { char *encrypted; int r; /* cp points to a static buffer */ cp = bb_ask(STDIN_FILENO, timeout, "Give root password for system maintenance\n" "(or type Control-D for normal startup):"); if (!cp) { /* ^D, ^C, timeout, or read error */ bb_info_msg("Normal startup"); return 0; } encrypted = pw_encrypt(cp, pwd->pw_passwd, 1); r = strcmp(encrypted, pwd->pw_passwd); free(encrypted); if (r == 0) { break; } bb_do_delay(LOGIN_FAIL_DELAY); bb_info_msg("Login incorrect"); } memset(cp, 0, strlen(cp)); // signal(SIGALRM, SIG_DFL); bb_info_msg("System Maintenance Mode"); IF_SELINUX(renew_current_security_context()); shell = getenv("SUSHELL"); if (!shell) shell = getenv("sushell"); if (!shell) shell = pwd->pw_shell; /* Exec login shell with no additional parameters. Never returns. */ run_shell(shell, 1, NULL, NULL); auth_error: bb_error_msg_and_die("no password entry for root"); }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); hash += "\n"; { char *in, *out; in = strdup(hash.c_str()); out = (char*)calloc(1, hash.size()); if (in && out) { BIO *b64, *bmem; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new_mem_buf(in, hash.size()); bmem = BIO_push(b64, bmem); BIO_read(bmem, out, hash.size()); BIO_free_all(bmem); authentication.append(out, hash.size()); } free(in); free(out); } pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); pos = serviceref.find('?'); if (pos == std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) running = true; } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); pos = request.find("?bitrate="); if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; sscanf(request.substr(pos).c_str(), "?bitrate=%d", &bitrate); pos = request.find("?width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?width=%d", &width); pos = request.find("?height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?height=%d", &height); pos = request.find("?framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?framerate=%d", &framerate); pos = request.find("?interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?interlaced=%d", &interlaced); pos = request.find("?aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?aspectratio=%d", &aspectratio); encoderFd = parent->allocateEncoder(this, serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }
/* * This function looks up "username" in the shadow password file, determines * the hash algorithm type, and returns the salt and the password * hash for that user. * * Given the salt and the user password, then the hash can be created. * The generated hash is used as an SRP password (client side), and * the generator for the SRP secret (server side). * * Crypt password file format references: * http://php.net/manual/en/function.crypt.php * http://en.wikipedia.org/wiki/Crypt_%28C%29#Blowfish-based_scheme * * Look up from the shadow password file the specified user, and if found, * return the salt field parsed out from the hash entry * * Algorithm ID * $1$ MD5 * 12 characters salt follows * * $2a$ Blowfish * $2b$ Blowfish * $2x$ Blowfish * $2y$ Blowfish * Blowfish salt format: * $id$NN$-----22 chars-salt----++++++hash+++++: * * SHA salt format * $5$ SHA-256 * $6$ SHA-512 * $ID$salt$hash */ int get_sp_salt(const char *username, char **ret_salt, char **ret_encpwd) { int st = 0; int is_locked = 0; struct spwd *spval = NULL; struct spwd spval_buf = {0}; char *spbuf_str = NULL; int spbuf_str_len = 256; int salt_len = 0; char *salt = NULL; char *encpwd = NULL; char *sp = NULL; int cur_uid = 0; int error = 0; if (!username || !ret_salt || !ret_encpwd) { st = -1; errno = EINVAL; goto error; } /* Must be root to read shadow password file */ cur_uid = getuid(); error = seteuid(0); if (error != 0) { st = -1; goto error; } /* Obtain password file lock, and hold minimum amount of time */ st = lckpwdf(); if (st == -1) { goto error; } is_locked = 1; spbuf_str = calloc(spbuf_str_len, sizeof(char)); if (!spbuf_str) { st = -1; goto error; } st = getspnam_r(username, &spval_buf, spbuf_str, spbuf_str_len, &spval); if (!spval || st == -1) { /* Failed due to permissions or entry not found */ st = -1; goto error; } salt = strdup(spval->sp_pwdp); if (!salt) { /* errno is set */ st = -1; goto error; } encpwd = strdup(spval->sp_pwdp); if (!encpwd) { /* errno is set */ st = -1; goto error; } ulckpwdf(); error = seteuid(cur_uid); if (error != 0) { st = -1; goto error; } is_locked = 0; /* CRYPT_DES hash is not supported; how to test? */ /* Determine the hash algorithn, and therefore the salt length */ if (!strncmp(salt, CRYPT_MD5, strlen(CRYPT_MD5))) { /* $1$123456789012 */ salt_len = 12 + 3; } else if (!strncmp(salt, CRYPT_BLOWFISH_2A, strlen(CRYPT_BLOWFISH_2A)) || !strncmp(salt, CRYPT_BLOWFISH_2B, strlen(CRYPT_BLOWFISH_2B)) || !strncmp(salt, CRYPT_BLOWFISH_2X, strlen(CRYPT_BLOWFISH_2X)) || !strncmp(salt, CRYPT_BLOWFISH_2Y, strlen(CRYPT_BLOWFISH_2Y))) { /* $2a$05$1234567890123456789012 */ salt_len = 22 + 7; } else if (!strncmp(salt, CRYPT_SHA_256, strlen(CRYPT_SHA_256)) || !strncmp(salt, CRYPT_SHA_512, strlen(CRYPT_SHA_512))) { sp = strrchr(salt, '$'); salt_len = sp - salt + 1; } if(salt_len == 0)//locked user, user with nologin etc { st = -1; errno = EPERM; goto error; } salt[salt_len] = '\0'; *ret_salt = salt; *ret_encpwd = encpwd; salt = NULL; error: if (is_locked) { ulckpwdf(); error = seteuid(cur_uid); } if (spbuf_str) { free(spbuf_str); } if (st == -1) { if (salt) { free(salt); salt = NULL; } if (encpwd) { free(encpwd); encpwd = NULL; } } return st; }
int sulogin_main(int argc, char **argv) { char *cp; int timeout = 0; char *timeout_arg; const char * const *p; struct passwd *pwd; const char *shell; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ char buffer[256]; struct spwd spw; struct spwd *result; #endif logmode = LOGMODE_BOTH; openlog(applet_name, 0, LOG_AUTH); if (getopt32(argc, argv, "t:", &timeout_arg)) { timeout = xatoi_u(timeout_arg); } if (argv[optind]) { close(0); close(1); dup(xopen(argv[optind], O_RDWR)); close(2); dup(0); } if (!isatty(0) || !isatty(1) || !isatty(2)) { logmode = LOGMODE_SYSLOG; bb_error_msg_and_die("not a tty"); } /* Clear out anything dangerous from the environment */ for (p = forbid; *p; p++) unsetenv(*p); signal(SIGALRM, catchalarm); pwd = getpwuid(0); if (!pwd) { goto auth_error; } #if ENABLE_FEATURE_SHADOWPASSWDS if (getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result)) { goto auth_error; } pwd->pw_passwd = spw.sp_pwdp; #endif while (1) { /* cp points to a static buffer that is zeroed every time */ cp = bb_askpass(timeout, "Give root password for system maintenance\n" "(or type Control-D for normal startup):"); if (!cp || !*cp) { bb_info_msg("Normal startup"); return 0; } if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) { break; } bb_do_delay(FAIL_DELAY); bb_error_msg("login incorrect"); } memset(cp, 0, strlen(cp)); signal(SIGALRM, SIG_DFL); bb_info_msg("System Maintenance Mode"); USE_SELINUX(renew_current_security_context()); shell = getenv("SUSHELL"); if (!shell) shell = getenv("sushell"); if (!shell) { shell = "/bin/sh"; if (pwd->pw_shell[0]) shell = pwd->pw_shell; } run_shell(shell, 1, 0, 0); /* never returns */ auth_error: bb_error_msg_and_die("no password entry for 'root'"); }
static void main_loop(char *devname, boolean_t cttyflag) { int fd, fb, i; char *user = NULL; /* authorized user */ char *pass; /* password from user */ char *cpass; /* crypted password */ struct spwd spwd; struct spwd *lshpw; /* local shadow */ char shadow[NSS_BUFLEN_SHADOW]; FILE *sysmsgfd; for (i = 0; i < 3; i++) (void) close(i); if (cttyflag == B_FALSE) { if (setsid() == -1) exit(EXIT_FAILURE); } if ((fd = open(devname, O_RDWR)) < 0) exit(EXIT_FAILURE); /* * In system maintenance mode, all virtual console instances * of the svc:/system/console-login service are not available * any more, and only the system console is available. So here * we always switch to the system console in case at the moment * the active console isn't it. */ (void) ioctl(fd, VT_ACTIVATE, 1); if (fd != 0) (void) dup2(fd, STDIN_FILENO); if (fd != 1) (void) dup2(fd, STDOUT_FILENO); if (fd != 2) (void) dup2(fd, STDERR_FILENO); if (fd > 2) (void) close(fd); /* Stop progress bar and reset console mode to text */ if ((fb = open("/dev/fb", O_RDONLY)) >= 0) { (void) ioctl(fb, KDSETMODE, KD_RESETTEXT); (void) close(fb); } sysmsgfd = fopen("/dev/sysmsg", "w"); sanitize_tty(fileno(stdin)); for (;;) { do { (void) printf("\nEnter user name for system " "maintenance (control-d to bypass): "); user = sulogin_getinput(devname, ECHOON); if (user == NULL) { /* signal other children to exit */ (void) sigsend(P_PID, masterpid, SIGUSR1); /* ^D, so straight to default init state */ exit(EXIT_FAILURE); } } while (user[0] == '\0'); (void) printf("Enter %s password (control-d to bypass): ", user); if ((pass = sulogin_getinput(devname, ECHOOFF)) == NULL) { /* signal other children to exit */ (void) sigsend(P_PID, masterpid, SIGUSR1); /* ^D, so straight to default init state */ free(user); exit(EXIT_FAILURE); } lshpw = getspnam_r(user, &spwd, shadow, sizeof (shadow)); if (lshpw == NULL) { /* * the user entered doesn't exist, too bad. */ goto sorry; } /* * There is a special case error to catch here: * If the password is hashed with an algorithm * other than the old unix crypt the call to crypt(3c) * could fail if /usr is corrupt or not available * since by default /etc/security/crypt.conf will * have the crypt_ modules located under /usr/lib. * Or it could happen if /etc/security/crypt.conf * is corrupted. * * If this happens crypt(3c) will return NULL and * set errno to ELIBACC for the former condition or * EINVAL for the latter, in this case we bypass * authentication and just verify that the user is * authorized. */ errno = 0; cpass = crypt(pass, lshpw->sp_pwdp); if (((cpass == NULL) && (lshpw->sp_pwdp[0] == '$')) && ((errno == ELIBACC) || (errno == EINVAL))) { goto checkauth; } else if ((cpass == NULL) || (strcmp(cpass, lshpw->sp_pwdp) != 0)) { goto sorry; } checkauth: /* * There is a special case error here as well. * If /etc/user_attr is corrupt, getusernam("root") * returns NULL. * In this case, we just give access because this is similar * to the case of root not existing in /etc/passwd. */ if ((getusernam("root") != NULL) && (chkauthattr(MAINTENANCE_AUTH, user) != 1)) { goto sorry; } (void) fprintf(sysmsgfd, "\nsingle-user privilege " "assigned to %s on %s.\n", user, devname); (void) sigsend(P_PID, masterpid, SIGUSR1); (void) wait(NULL); free(user); free(pass); single(su, devname); /* single never returns */ sorry: (void) printf("\nLogin incorrect or user %s not authorized\n", user); free(user); free(pass); (void) sleep(sleeptime); } }
/*ARGSUSED*/ int nss_getpwnam(char *name, attrlist *items, pwu_repository_t *rep, void **buf) { attrlist *p; struct pwbuf *pwbuf; int repositories = REP_ERANGE; /* changed if ATTR_REP_NAME is set */ int err = PWU_SUCCESS; *buf = calloc(1, sizeof (struct pwbuf)); pwbuf = (struct pwbuf *)*buf; /* * determine which password structure (/etc/passwd or /etc/shadow) * we need for the items we need to update */ for (p = items; p != NULL; p = p->next) { switch (p->type) { case ATTR_NAME: case ATTR_UID: case ATTR_GID: case ATTR_AGE: case ATTR_COMMENT: case ATTR_GECOS: case ATTR_HOMEDIR: case ATTR_SHELL: if (pwbuf->pwd == NULL) pwbuf->pwd = (struct passwd *) malloc(sizeof (struct passwd)); if (pwbuf->pwd == NULL) { errno = ENOMEM; if (pwbuf->spwd) free(pwbuf->spwd); return (PWU_NOMEM); } break; case ATTR_PASSWD: case ATTR_PASSWD_SERVER_POLICY: case ATTR_LSTCHG: case ATTR_MIN: case ATTR_MAX: case ATTR_WARN: case ATTR_INACT: case ATTR_EXPIRE: case ATTR_FLAG: case ATTR_LOCK_ACCOUNT: case ATTR_EXPIRE_PASSWORD: case ATTR_FAILED_LOGINS: if (pwbuf->spwd == NULL) pwbuf->spwd = (struct spwd *) malloc(sizeof (struct spwd)); if (pwbuf->spwd == NULL) { errno = ENOMEM; if (pwbuf->pwd) free(pwbuf->pwd); return (PWU_NOMEM); } break; case ATTR_REP_NAME: /* get the compat names (REP_COMPAT_*) */ repositories = get_ns(rep, PWU_READ); break; default: /* * Some other repository might have different values * so we ignore those. */ break; } } if (pwbuf->pwd) { if ((pwbuf->pwd_scratch = malloc(PWD_SCRATCH_SIZE)) == NULL) { err = PWU_NOMEM; goto error; } if (getpwnam_r(name, pwbuf->pwd, pwbuf->pwd_scratch, PWD_SCRATCH_SIZE) == NULL) { err = PWU_NOT_FOUND; goto error; } } if (pwbuf->spwd) { if ((pwbuf->spwd_scratch = malloc(SPW_SCRATCH_SIZE)) == NULL) { err = PWU_NOMEM; goto error; } if (getspnam_r(name, pwbuf->spwd, pwbuf->spwd_scratch, SPW_SCRATCH_SIZE) == NULL) { err = PWU_NOT_FOUND; goto error; } } /* pwbuf->rep_name tells us where the user in fact comes from */ if (repositories != REP_ERANGE) { struct passwd pwd; char pwd_scratch[PWD_SCRATCH_SIZE]; /* can we find the user locally? */ if (private_getpwnam_r(name, &pwd, pwd_scratch, PWD_SCRATCH_SIZE) != NULL) pwbuf->rep_name = "files"; else if (repositories & REP_COMPAT_NISPLUS) pwbuf->rep_name = "nisplus"; else if (repositories & REP_COMPAT_LDAP) pwbuf->rep_name = "ldap"; else if (repositories & REP_COMPAT_NIS) pwbuf->rep_name = "nis"; else pwbuf->rep_name = "nss"; } else pwbuf->rep_name = "nss"; return (PWU_SUCCESS); error: if (pwbuf->pwd) free(pwbuf->pwd); if (pwbuf->pwd_scratch) free(pwbuf->pwd_scratch); if (pwbuf->spwd) free(pwbuf->spwd); if (pwbuf->spwd_scratch) free(pwbuf->spwd_scratch); free(pwbuf); *buf = NULL; return (err); }
int shadow_user_pass_verify(const char *username, const char *password) { #if defined(COMPILE_WIN32) || defined(NO_SHADOW_H) errno = ENOSYS; return -1; #else int errsv = 0; struct spwd *spentp = NULL; size_t salt_len = 0; char *salt = NULL, *local_hash = NULL, *user_hash = NULL; #ifdef _GNU_SOURCE char sp_buf[8192]; struct spwd spent; struct crypt_data cd; #endif /* Pre-check */ if (!username || !password) { errno = EINVAL; return -1; } #if defined(_GNU_SOURCE) /* GNU implementations support native reentrant functions */ if (getspnam_r(username, &spent, sp_buf, sizeof(sp_buf), &spentp) < 0) return -1; #else pthread_mutex_lock(&_auth_shadow_mutex); spentp = getspnam(username); errsv = errno; pthread_mutex_unlock(&_auth_shadow_mutex); #endif /* Validate that spentp is valid */ if (!spentp) { errno = errsv; return -1; } /* Search for '$' in the local hash. If found, extensions (non-POSIX) are enabled */ if (!(local_hash = strrchr(spentp->sp_pwdp, '$'))) { /* DES (default) */ if (strlen(spentp->sp_pwdp) <= 2) { errno = ENOSYS; return -1; } salt_len = 2; } else { /* Extensions */ local_hash ++; salt_len = local_hash - spentp->sp_pwdp; } /* Allocate memory for salt */ if (!(salt = malloc(salt_len + 1))) return -1; /* Isolate salt */ memcpy(salt, spentp->sp_pwdp, salt_len); salt[salt_len] = 0; #ifdef _GNU_SOURCE /* cd.initialized = 0; */ tc_memset(&cd, 0, sizeof(struct crypt_data)); /* Generate password hash */ if (!(user_hash = crypt_r(password, salt, &cd))) { errsv = errno; free(salt); errno = errsv; return -1; } #else pthread_mutex_lock(&_auth_shadow_mutex); /* Generate password hash (non-reentrant) */ if (!(user_hash = crypt(password, salt))) { errsv = errno; free(salt); errno = errsv; return -1; } pthread_mutex_unlock(&_auth_shadow_mutex); #endif /* Free unused memory */ free(salt); /* Compare hashes */ if (strcmp(spentp->sp_pwdp, user_hash)) { errno = EINVAL; return -1; } return 0; #endif }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_DARWIN) RTLogPrintf("rtCheckCredentials\n"); /* * Resolve user to UID and GID. */ char szBuf[_4K]; struct passwd Pw; struct passwd *pPw; if (getpwnam_r(pszUser, &Pw, szBuf, sizeof(szBuf), &pPw) != 0) return VERR_AUTHENTICATION_FAILURE; if (!pPw) return VERR_AUTHENTICATION_FAILURE; *pUid = pPw->pw_uid; *pGid = pPw->pw_gid; /* * Use PAM for the authentication. * Note! libpam.2.dylib was introduced with 10.6.x (OpenPAM). */ void *hModPam = dlopen("libpam.dylib", RTLD_LAZY | RTLD_GLOBAL); if (hModPam) { int (*pfnPamStart)(const char *, const char *, struct pam_conv *, pam_handle_t **); int (*pfnPamAuthenticate)(pam_handle_t *, int); int (*pfnPamAcctMgmt)(pam_handle_t *, int); int (*pfnPamSetItem)(pam_handle_t *, int, const void *); int (*pfnPamEnd)(pam_handle_t *, int); *(void **)&pfnPamStart = dlsym(hModPam, "pam_start"); *(void **)&pfnPamAuthenticate = dlsym(hModPam, "pam_authenticate"); *(void **)&pfnPamAcctMgmt = dlsym(hModPam, "pam_acct_mgmt"); *(void **)&pfnPamSetItem = dlsym(hModPam, "pam_set_item"); *(void **)&pfnPamEnd = dlsym(hModPam, "pam_end"); ASMCompilerBarrier(); if ( pfnPamStart && pfnPamAuthenticate && pfnPamAcctMgmt && pfnPamSetItem && pfnPamEnd) { #define pam_start pfnPamStart #define pam_authenticate pfnPamAuthenticate #define pam_acct_mgmt pfnPamAcctMgmt #define pam_set_item pfnPamSetItem #define pam_end pfnPamEnd /* Do the PAM stuff. Note! Abusing 'login' here for now... */ pam_handle_t *hPam = NULL; RTPROCPAMARGS PamConvArgs = { pszUser, pszPasswd }; struct pam_conv PamConversation; RT_ZERO(PamConversation); PamConversation.appdata_ptr = &PamConvArgs; PamConversation.conv = rtPamConv; int rc = pam_start("login", pszUser, &PamConversation, &hPam); if (rc == PAM_SUCCESS) { rc = pam_set_item(hPam, PAM_RUSER, pszUser); if (rc == PAM_SUCCESS) rc = pam_authenticate(hPam, 0); if (rc == PAM_SUCCESS) { rc = pam_acct_mgmt(hPam, 0); if ( rc == PAM_SUCCESS || rc == PAM_AUTHINFO_UNAVAIL /*??*/) { pam_end(hPam, PAM_SUCCESS); dlclose(hModPam); return VINF_SUCCESS; } Log(("rtCheckCredentials: pam_acct_mgmt -> %d\n", rc)); } else Log(("rtCheckCredentials: pam_authenticate -> %d\n", rc)); pam_end(hPam, rc); } else Log(("rtCheckCredentials: pam_start -> %d\n", rc)); } else Log(("rtCheckCredentials: failed to resolve symbols: %p %p %p %p %p\n", pfnPamStart, pfnPamAuthenticate, pfnPamAcctMgmt, pfnPamSetItem, pfnPamEnd)); dlclose(hModPam); } else Log(("rtCheckCredentials: Loading libpam.dylib failed\n")); return VERR_AUTHENTICATION_FAILURE; #elif defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
void eStreamClient::notifier(int what) { if (what & eSocketNotifier::Read) { char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (!running) { if (request.find('\n') != std::string::npos) { if (request.substr(0, 5) == "GET /") { size_t pos; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); hash += "\n"; { char *in, *out; in = strdup(hash.c_str()); out = (char*)calloc(1, hash.size()); if (in && out) { BIO *b64, *bmem; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new_mem_buf(in, hash.size()); bmem = BIO_push(b64, bmem); BIO_read(bmem, out, hash.size()); BIO_free_all(bmem); authentication.append(out, hash.size()); } free(in); free(out); } pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); } } } }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; size_t posdur; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); authentication = base64decode(hash); pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); /* We don't expect any incoming data, so set a tiny buffer */ set_socket_option(streamFd, SO_RCVBUF, 1 * 1024); /* We like 188k packets, so set the TCP window size to that */ set_socket_option(streamFd, SO_SNDBUF, 188 * 1024); /* activate keepalive */ set_socket_option(streamFd, SO_KEEPALIVE, 1); /* configure keepalive */ set_tcp_option(streamFd, TCP_KEEPINTVL, 10); // every 10 seconds set_tcp_option(streamFd, TCP_KEEPIDLE, 1); // after 1 second of idle set_tcp_option(streamFd, TCP_KEEPCNT, 2); // drop connection after second miss /* also set 10 seconds data push timeout */ set_tcp_option(streamFd, TCP_USER_TIMEOUT, 10 * 1000); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); /* Strip session ID from URL if it exists, PLi streaming can not handle it */ pos = serviceref.find("&sessionid="); if (pos != std::string::npos) { serviceref.erase(pos, std::string::npos); } pos = serviceref.find("?sessionid="); if (pos != std::string::npos) { serviceref.erase(pos, std::string::npos); } pos = serviceref.find('?'); if (pos == std::string::npos) { eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); pos = request.find("?bitrate="); posdur = request.find("?duration="); eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (posdur != std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } int timeout = 0; sscanf(request.substr(posdur).c_str(), "?duration=%d", &timeout); eDebug("[eDVBServiceStream] duration: %d seconds", timeout); if (timeout) { m_timeout->startLongTimer(timeout); } } else if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; sscanf(request.substr(pos).c_str(), "?bitrate=%d", &bitrate); pos = request.find("?width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?width=%d", &width); pos = request.find("?height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?height=%d", &height); pos = request.find("?framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?framerate=%d", &framerate); pos = request.find("?interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?interlaced=%d", &interlaced); pos = request.find("?aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?aspectratio=%d", &aspectratio); encoderFd = -1; if (eEncoder::getInstance()) encoderFd = eEncoder::getInstance()->allocateEncoder(serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } m_serviceref = serviceref; m_useencoder = true; } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }
int passwd_main(int argc UNUSED_PARAM, char **argv) { enum { OPT_algo = (1 << 0), /* -a - password algorithm */ OPT_lock = (1 << 1), /* -l - lock account */ OPT_unlock = (1 << 2), /* -u - unlock account */ OPT_delete = (1 << 3), /* -d - delete password */ OPT_lud = OPT_lock | OPT_unlock | OPT_delete, }; unsigned opt; int rc; const char *opt_a = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; const char *filename; char *myname; char *name; char *newp; struct passwd *pw; uid_t myuid; struct rlimit rlimit_fsize; char c; #if ENABLE_FEATURE_SHADOWPASSWDS /* Using _r function to avoid pulling in static buffers */ struct spwd spw; char buffer[256]; #endif logmode = LOGMODE_BOTH; openlog(applet_name, 0, LOG_AUTH); opt = getopt32(argv, "a:lud", &opt_a); //argc -= optind; argv += optind; myuid = getuid(); /* -l, -u, -d require root priv and username argument */ if ((opt & OPT_lud) && (myuid != 0 || !argv[0])) bb_show_usage(); /* Will complain and die if username not found */ myname = xstrdup(xuid2uname(myuid)); name = argv[0] ? argv[0] : myname; pw = xgetpwnam(name); if (myuid != 0 && pw->pw_uid != myuid) { /* LOGMODE_BOTH */ bb_error_msg_and_die("%s can't change password for %s", myname, name); } #if ENABLE_FEATURE_SHADOWPASSWDS { /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; errno = 0; if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result) != 0 || !result /* no error, but no record found either */ || strcmp(result->sp_namp, pw->pw_name) != 0 /* paranoia */ ) { if (errno != ENOENT) { /* LOGMODE_BOTH */ bb_perror_msg("no record of %s in %s, using %s", name, bb_path_shadow_file, bb_path_passwd_file); } /* else: /etc/shadow does not exist, * apparently we are on a shadow-less system, * no surprise there */ } else { pw->pw_passwd = result->sp_pwdp; } } #endif /* Decide what the new password will be */ newp = NULL; c = pw->pw_passwd[0] - '!'; if (!(opt & OPT_lud)) { if (myuid != 0 && !c) { /* passwd starts with '!' */ /* LOGMODE_BOTH */ bb_error_msg_and_die("can't change " "locked password for %s", name); } printf("Changing password for %s\n", name); newp = new_password(pw, myuid, opt_a); if (!newp) { logmode = LOGMODE_STDIO; bb_error_msg_and_die("password for %s is unchanged", name); } } else if (opt & OPT_lock) { if (!c) goto skip; /* passwd starts with '!' */ newp = xasprintf("!%s", pw->pw_passwd); } else if (opt & OPT_unlock) { if (c) goto skip; /* not '!' */ /* pw->pw_passwd points to static storage, * strdup'ing to avoid nasty surprizes */ newp = xstrdup(&pw->pw_passwd[1]); } else if (opt & OPT_delete) { newp = (char*)""; } rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000; setrlimit(RLIMIT_FSIZE, &rlimit_fsize); bb_signals(0 + (1 << SIGHUP) + (1 << SIGINT) + (1 << SIGQUIT) , SIG_IGN); umask(077); xsetuid(0); #if ENABLE_FEATURE_SHADOWPASSWDS filename = bb_path_shadow_file; rc = update_passwd(bb_path_shadow_file, name, newp, NULL); if (rc > 0) /* password in /etc/shadow was updated */ newp = (char*) "x"; if (rc >= 0) /* 0 = /etc/shadow missing (not an error), >0 = passwd changed in /etc/shadow */ #endif { filename = bb_path_passwd_file; rc = update_passwd(bb_path_passwd_file, name, newp, NULL); } /* LOGMODE_BOTH */ if (rc < 0) bb_error_msg_and_die("can't update password file %s", filename); bb_error_msg("password for %s changed by %s", name, myname); /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ skip: if (!newp) { bb_error_msg_and_die("password for %s is already %slocked", name, (opt & OPT_unlock) ? "un" : ""); } if (ENABLE_FEATURE_CLEAN_UP) free(myname); return 0; }
struct spwd * pam_modutil_getspnam(pam_handle_t *pamh, const char *user) { #ifdef HAVE_GETSPNAM_R void *buffer=NULL; size_t length = PWD_INITIAL_LENGTH; do { int status; void *new_buffer; struct spwd *result = NULL; new_buffer = realloc(buffer, sizeof(struct spwd) + length); if (new_buffer == NULL) { D(("out of memory")); /* no memory for the user - so delete the memory */ if (buffer) { free(buffer); } return NULL; } buffer = new_buffer; /* make the re-entrant call to get the spwd structure */ errno = 0; status = getspnam_r(user, buffer, sizeof(struct spwd) + (char *) buffer, length, &result); if (!status && (result == buffer)) { char *data_name; const void *ignore; int i; data_name = malloc(strlen("_pammodutil_getspnam") + 1 + strlen(user) + 1 + intlen(INT_MAX) + 1); if ((pamh != NULL) && (data_name == NULL)) { D(("was unable to register the data item [%s]", pam_strerror(pamh, status))); free(buffer); return NULL; } if (pamh != NULL) { for (i = 0; i < INT_MAX; i++) { sprintf(data_name, "_pammodutil_getspnam_%s_%d", user, i); status = PAM_NO_MODULE_DATA; if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { status = pam_set_data(pamh, data_name, result, pam_modutil_cleanup); } if (status == PAM_SUCCESS) { break; } } } else { status = PAM_SUCCESS; } free(data_name); if (status == PAM_SUCCESS) { D(("success")); return result; } D(("was unable to register the data item [%s]", pam_strerror(pamh, status))); free(buffer); return NULL; } else if (errno != ERANGE && errno != EINTR) { /* no sense in repeating the call */ break; } length <<= PWD_LENGTH_SHIFT; } while (length < PWD_ABSURD_PWD_LENGTH); D(("spwd structure took %u bytes or so of memory", length+sizeof(struct spwd))); free(buffer); return NULL; #else /* ie. ifndef HAVE_GETSPNAM_R */ /* * Sorry, there does not appear to be a reentrant version of * getspnam(). So, we use the standard libc function. */ return getspnam(user); #endif /* def HAVE_GETSPNAM_R */ }