Beispiel #1
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
		    int argc, const char **argv)
{
	const char *user, *pass;
	int res;

	res = pam_get_user(pamh, &user, NULL);
	if (res != PAM_SUCCESS)
		return res;
	res = pam_get_authtok(pamh, PAM_AUTHTOK, &pass, NULL);
	if (res != PAM_SUCCESS)
		return res;

	if (askhelper(user, pass) != 0)
		return PAM_AUTH_ERR;

	return PAM_SUCCESS;
}
Beispiel #2
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
  int argc, const char *argv[])
{
#ifndef _OPENPAM
  const void *ptr;
  const struct pam_conv *conv;
  struct pam_message msg;
  const struct pam_message *msgp;
  struct pam_response *resp;
#endif
  struct passwd *pwd;
  const char *user;
  char *pad;
  int pam_err, retry;

  FILE *file = NULL;
  char *pw = NULL, *offset = NULL, *num = NULL;

  /* identify user */
  if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
    return (pam_err);
  if ((pwd = getpwnam(user)) == NULL)
    return (PAM_USER_UNKNOWN);

  /* get password */
#ifndef _OPENPAM
  pam_err = pam_get_item(pamh, PAM_CONV, &ptr);
  if (pam_err != PAM_SUCCESS)
    return (PAM_SYSTEM_ERR);
  conv = ptr;
  msg.msg_style = PAM_PROMPT_ECHO_ON;
  msg.msg = password_prompt;
  msgp = &msg;
#endif
  pad = NULL;
  for (retry = 0; retry < 3; ++retry) {
#ifdef _OPENPAM
    pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
        (const char **)&pad, NULL);
#else
    resp = NULL;
    pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
    if (resp != NULL) {
      if (pam_err == PAM_SUCCESS)
        pad = resp->resp;
      else
        free(resp->resp);
      free(resp);
    }
  // change to PAM_PROMPT_ECHO_OFF, if you want no password-echo
  msg.msg_style = PAM_PROMPT_ECHO_ON;
#endif
    if (pam_err == PAM_SUCCESS)
      break;
  }

  if (pam_err == PAM_CONV_ERR)
    return (pam_err);
  if (pam_err != PAM_SUCCESS)
    return (PAM_AUTH_ERR);

  // open file
  if((file = fopen(PASSWD_FILE, "r+")) == NULL)
    return PAM_AUTH_ERR;

  // parse file
  if(_parse_passwd(file, user, &pw, &offset, &num) != 0)
    return _cleanup(file, PAM_AUTH_ERR);

  // check, if authentication is successfull
  int i;
  if((i = openkubus_authenticate(pad, pw, atoi(offset), atoi(num))) > 0)
  {
    // update number in password file
    _update_passwd(file, num, i+1);

    return _cleanup(file, PAM_SUCCESS);
  }

  return _cleanup(file, PAM_AUTH_ERR);
}
Beispiel #3
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
	int argc, const char *argv[])
{
#ifndef OPENPAM
	struct pam_conv *conv;
	struct pam_message msg;
	const struct pam_message *msgp;
	struct pam_response *resp;
#endif
	struct passwd *pwd;
	const char *user;
	char *crypt_password, *password;
	int pam_err, retry;

	(void)argc;
	(void)argv;

	/* identify user */
	if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
		return (pam_err);
	if ((pwd = getpwnam(user)) == NULL)
		return (PAM_USER_UNKNOWN);

	/* get password */
#ifndef OPENPAM
	pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
	if (pam_err != PAM_SUCCESS)
		return (PAM_SYSTEM_ERR);
	msg.msg_style = PAM_PROMPT_ECHO_OFF;
	msg.msg = password_prompt;
	msgp = &msg;
#endif
	for (retry = 0; retry < 3; ++retry) {
#ifdef OPENPAM
		pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
		    (const char **)&password, NULL);
#else
		resp = NULL;
		pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
		if (resp != NULL) {
			if (pam_err == PAM_SUCCESS)
				password = resp->resp;
			else
				free(resp->resp);
			free(resp);
		}
#endif
		if (pam_err == PAM_SUCCESS)
			break;
	}
	if (pam_err == PAM_CONV_ERR)
		return (pam_err);
	if (pam_err != PAM_SUCCESS)
		return (PAM_AUTH_ERR);

	/* compare passwords */
	if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) ||
	    (crypt_password = crypt(password, pwd->pw_passwd)) == NULL ||
	    strcmp(crypt_password, pwd->pw_passwd) != 0)
		pam_err = PAM_AUTH_ERR;
	else
		pam_err = PAM_SUCCESS;
#ifndef OPENPAM
	free(password);
#endif
	return (pam_err);
}
Beispiel #4
0
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
				   int argc, const char **argv) {
    int i;
    const char *name;
    char const * password;
    char const * pwdfilename = NULL;
    char const * stored_crypted_password = NULL;
    char const * crypted_password;
    FILE *pwdfile;
    int use_flock = 0;
    int use_delay = 1;
    int legacy_crypt = 0;
    int debug = 0;
    char * linebuf = NULL;
    size_t linebuflen;
#ifdef USE_CRYPT_R
    struct crypt_data crypt_buf;
#endif
    
    /* we require the pwdfile switch and argument to be present, else we don't work */
    for (i = 0; i < argc; ++i) {
	if (!strcmp(argv[i], "pwdfile") && i + 1 < argc)
	    pwdfilename = argv[++i];
	else if (!strncmp(argv[i], "pwdfile=", strlen("pwdfile=")))
	    pwdfilename = argv[i] + strlen("pwdfile=");
	else if (!strcmp(argv[i], "flock"))
	    use_flock = 1;
	else if (!strcmp(argv[i], "noflock"))
	    use_flock = 0;
	else if (!strcmp(argv[i], "nodelay"))
	    use_delay = 0;
	else if (!strcmp(argv[i], "debug"))
	    debug = 1;
	else if (!strcmp(argv[i], "legacy_crypt"))
	    legacy_crypt = 1;
    }
    
#ifdef HAVE_PAM_FAIL_DELAY
    if (use_delay) {
	if (debug) pam_syslog(pamh, LOG_DEBUG, "setting fail delay");
	(void) pam_fail_delay(pamh, 2000000);   /* 2 sec */
    }
#endif
    
    if (!pwdfilename) {
	pam_syslog(pamh, LOG_ERR, "password file name not specified");
	return PAM_AUTHINFO_UNAVAIL;
    }
    
    if (pam_get_user(pamh, &name, NULL) != PAM_SUCCESS) {
	pam_syslog(pamh, LOG_ERR, "couldn't get username from PAM stack");
	return PAM_AUTH_ERR;
    }
    if (debug) pam_syslog(pamh, LOG_DEBUG, "username is %s", name);
    
    if (!(pwdfile = fopen(pwdfilename, "r"))) {
	pam_syslog(pamh, LOG_ALERT, "couldn't open password file %s", pwdfilename);
	return PAM_AUTHINFO_UNAVAIL;
    }
    
    if (use_flock && lock_fd(fileno(pwdfile)) == -1) {
	pam_syslog(pamh, LOG_ALERT, "couldn't lock password file %s", pwdfilename);
	fclose(pwdfile);
	return PAM_AUTHINFO_UNAVAIL;
    }
    
    /* get the crypted password corresponding to this user out of pwdfile */
    while (getline(&linebuf, &linebuflen, pwdfile) > 0) {
	/* strsep changes its argument, make a copy */
	char * nexttok = linebuf;
	
	/* first field: username */
	char * curtok = strsep(&nexttok, ":");
	
	/* skip non-matching usernames */
	if (strcmp(curtok, name))
	    continue;
	
	/* second field: password (until next colon or newline) */
	if ((curtok = strsep(&nexttok, ":\n"))) {
	    stored_crypted_password = curtok;
	    break;
	}
    }
    fclose(pwdfile);
    /* we keep linebuf (allocated by getline), stored_crypted_password is pointing into it */

    if (!stored_crypted_password)
	if (debug) pam_syslog(pamh, LOG_ERR, "user not found in password database");
    
    if (stored_crypted_password && !strlen(stored_crypted_password)) {
	if (debug) pam_syslog(pamh, LOG_DEBUG, "user has empty password field");
	free(linebuf);
	return flags & PAM_DISALLOW_NULL_AUTHTOK ? PAM_AUTH_ERR : PAM_SUCCESS;
    }
    
    if (pam_get_authtok(pamh, PAM_AUTHTOK, &password, NULL) != PAM_SUCCESS) {
	pam_syslog(pamh, LOG_ERR, "couldn't get password from PAM stack");
	free(linebuf);
	return PAM_AUTH_ERR;
    }
    
    if (!stored_crypted_password) {
	free(linebuf);
	return PAM_USER_UNKNOWN;
    }
    
    if (debug) pam_syslog(pamh, LOG_DEBUG, "got crypted password == '%s'", stored_crypted_password);
    
#ifdef USE_CRYPT_R
    crypt_buf.initialized = 0;
    if (!(crypted_password = crypt_r(password, stored_crypted_password, &crypt_buf)))
#else
    if (!(crypted_password = crypt(password, stored_crypted_password)))
#endif
    {
	pam_syslog(pamh, LOG_ERR, "crypt() failed");
	free(linebuf);
	return PAM_AUTH_ERR;
    }
    
    if (legacy_crypt && strcmp(crypted_password, stored_crypted_password)) {
	if (!strncmp(stored_crypted_password, "$1$", 3))
	    crypted_password = Brokencrypt_md5(password, stored_crypted_password);
	else
	    crypted_password = bigcrypt(password, stored_crypted_password);
    }

    if (strcmp(crypted_password, stored_crypted_password)) {
	pam_syslog(pamh, LOG_NOTICE, "wrong password for user %s", name);
	free(linebuf);
	return PAM_AUTH_ERR;
    }
    
    if (debug) pam_syslog(pamh, LOG_DEBUG, "passwords match");
    free(linebuf);
    return PAM_SUCCESS;
}
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
                    int argc, const char *argv[])
{
    const char *user;
    char *password, *crypt_password, *cached_password;
    int pam_err, timestamp;

    /* identify user */
    if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
        return (pam_err);
    if (getpwnam(user) == NULL)
        return (PAM_USER_UNKNOWN);

    /* get password */
    pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
                              (const char **)&password, NULL);
    if (pam_err == PAM_CONV_ERR)
        return (pam_err);
    if (pam_err != PAM_SUCCESS)
        return (PAM_AUTH_ERR);

    cached_password = NULL;
    if (!read_ticket(user, &timestamp, &cached_password)) {
        pam_err = PAM_AUTH_ERR;
        if (crypt_set_format("sha512"))
            crypt_password = crypt(password, gen_salt());
        else
            crypt_password = NULL;
        goto done;
    }

    if ((crypt_password = crypt(password, cached_password)) != NULL &&
            strcmp(crypt_password, cached_password) == 0) {
        struct timespec now;
        clock_gettime(CLOCK_MONOTONIC, &now);
        /* TODO: timeout should be an argument! */
        if ((int)now.tv_sec > timestamp + TIMEOUT) {
            openpam_log(PAM_LOG_DEBUG,
                        "expired auth ticket: %d > %d",
                        (int)now.tv_sec, timestamp + TIMEOUT);
            pam_err = PAM_AUTH_ERR;
        } else {
            pam_err = PAM_SUCCESS;
        }
    } else {
        openpam_log(PAM_LOG_DEBUG, "passwords do not match");
        pam_err = PAM_AUTH_ERR;
    }
done:
    if (crypt_password != NULL) {
        char *cp;
        size_t len;
        len = strlen(crypt_password) + 1;
        if ((cp = calloc(len, sizeof(char))) != NULL &&
                strlcpy(cp, crypt_password, len) < len)
            pam_set_data(pamh, "pam_auth_ticket", cp, cleanup);
    }

    free(cached_password);
    return (pam_err);
}
Beispiel #6
0
int
pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
  struct passwd *pwd;
  const char *newpass;
  const char *user;
    int retval, tries;
  options_t options;

  memset (&options, 0, sizeof (options));

  /* Set some default values, which could be overwritten later.  */
  options.remember = 10;
  options.tries = 1;

  /* Parse parameters for module */
  for ( ; argc-- > 0; argv++)
    parse_option (pamh, *argv, &options);

  if (options.debug)
    pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered");


  if (options.remember == 0)
    return PAM_IGNORE;

  retval = pam_get_user (pamh, &user, NULL);
  if (retval != PAM_SUCCESS)
    return retval;

  if (user == NULL || strlen (user) == 0)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG,
		    "User is not known to system");

      return PAM_USER_UNKNOWN;
    }

  if (flags & PAM_PRELIM_CHECK)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG,
		    "pam_sm_chauthtok(PAM_PRELIM_CHECK)");

      return PAM_SUCCESS;
    }

  pwd = pam_modutil_getpwnam (pamh, user);
  if (pwd == NULL)
    return PAM_USER_UNKNOWN;

  if ((strcmp(pwd->pw_passwd, "x") == 0)  ||
      ((pwd->pw_passwd[0] == '#') &&
       (pwd->pw_passwd[1] == '#') &&
       (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
    {
      struct spwd *spw = pam_modutil_getspnam (pamh, user);
      if (spw == NULL)
	return PAM_USER_UNKNOWN;

      retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp,
			      options.remember, options.debug);
      if (retval != PAM_SUCCESS)
	return retval;
    }
  else
    {
      retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd,
			      options.remember, options.debug);
      if (retval != PAM_SUCCESS)
	return retval;
    }

  newpass = NULL;
  tries = 0;
  while ((newpass == NULL) && (tries < options.tries))
    {
      retval = pam_get_authtok (pamh, PAM_AUTHTOK, &newpass, NULL);
      if (retval != PAM_SUCCESS && retval != PAM_TRY_AGAIN)
	{
	  if (retval == PAM_CONV_AGAIN)
	    retval = PAM_INCOMPLETE;
	  return retval;
	}
      tries++;

      if (options.debug)
	{
	  if (newpass)
	    pam_syslog (pamh, LOG_DEBUG, "got new auth token");
	  else
	    pam_syslog (pamh, LOG_DEBUG, "got no auth token");
	}

      if (newpass == NULL || retval == PAM_TRY_AGAIN)
	continue;

      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG, "check against old password file");

      if (check_old_pass (pamh, user, newpass,
			  options.debug) != PAM_SUCCESS)
	{
	  if (getuid() || options.enforce_for_root ||
	      (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
	    {
	      pam_error (pamh,
		         _("Password has been already used. Choose another."));
	      newpass = NULL;
	      /* Remove password item, else following module will use it */
	      pam_set_item (pamh, PAM_AUTHTOK, (void *) NULL);
	    }
	  else
	    pam_info (pamh,
		       _("Password has been already used."));
	}
    }

  if (newpass == NULL && tries >= options.tries)
    {
      if (options.debug)
	pam_syslog (pamh, LOG_DEBUG, "Aborted, too many tries");
      return PAM_MAXTRIES;
    }

  return PAM_SUCCESS;
}
Beispiel #7
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
                    int argc, const char *argv[])
{
    const char *user;
    char *password;
    int pam_err, retry;

    const char *url = NULL;
    const char *service_user = NULL;
    const char *service_password = NULL;
    const char *group = NULL;
    const char *domain = NULL;
    int validate_certificate = 0;
    char *stripped_user = NULL;

    /* parse all parameters */
    {
        int i = 0;
        while (i < argc) {
            const char *val;

            if ((val = string_prefix_match(argv[i], "url=")) != NULL)
                url = val;
            else if ((val = string_prefix_match(argv[i], "service_user="******"service_password="******"group=")) != NULL)
                group = val;
            else if ((val = string_prefix_match(argv[i], "validate_certificate=")) != NULL)
                validate_certificate = !!strcmp(val, "no"); /* no = 0, everything else = 1 */
            else if ((val = string_prefix_match(argv[i], "domain=")) != NULL)
                domain = val;

            i++;
        }
    }

    /* complain about missing arguments, return error */
    if (!url || !(*url))
        syslog(LOG_AUTHPRIV|LOG_ERR, __FILE__": missing or empty required argument 'url'");
    if (!service_user)
        syslog(LOG_AUTHPRIV|LOG_ERR, __FILE__": missing required argument 'service_user'");
    if (!service_password)
        syslog(LOG_AUTHPRIV|LOG_ERR, __FILE__": missing required argument 'service_password'");

    if (!url || !(*url) || !service_user || !service_password)
        return PAM_AUTHINFO_UNAVAIL;

    /* get user */
    if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
        return (pam_err);

    /* get password - TODO why is this retry loop here? */
    for (retry = 0; retry < 3; retry++) {
        pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, (const char **)&password, NULL);
        if (pam_err == PAM_SUCCESS)
            break;
    }
    if (pam_err != PAM_SUCCESS)
        return (PAM_AUTH_ERR);

    /* strip domain & compare passwords */
    stripped_user = strip_domain(user, domain);
    
    if (stripped_user == NULL || pam_restauth_check(url, service_user, service_password,
                        group, validate_certificate, stripped_user, password)) {
        /* wait a bit */
        sleep(2);
        pam_err = PAM_AUTH_ERR; // TODO AUTHINFO_UNAVAIL (on hardware failure)
    } else {
        pam_err = PAM_SUCCESS;
    }
    
    if (stripped_user)
        free(stripped_user);

    return (pam_err);
}