예제 #1
0
파일: pam_cas.c 프로젝트: DICE-UNC/pam-cas
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
                        const char **argv)
{
    char *user, *pw;
    char *service;
    char **proxies;
    char netid[14];
    int i, success;
    Flags f = NONE;

    /* initialize proxy array */
    proxies = (char **)malloc(sizeof(char **));
    proxies[0] = NULL;

    /* get username and password */
    if (pam_get_user(pamh, (const char**) &user, NULL) != PAM_SUCCESS)
        return PAM_AUTH_ERR;
    if (pam_get_item(pamh, PAM_AUTHTOK, (const void**) &pw) != PAM_SUCCESS)
        return PAM_AUTH_ERR;

    /*
     * Abort if the password doesn't look like a ticket.  This speeds things
     * up and reduces the likelihood that the user's password will end up
     * in an HTTPD log.
     */
    if ((strncmp(CAS_BEGIN_PT, pw, strlen(CAS_BEGIN_PT)) != 0)
            && (strncmp(CAS_BEGIN_ST, pw, strlen(CAS_BEGIN_ST)) != 0))
        return PAM_AUTH_ERR;

    /* prepare log */
    openlog("PAM_cas", LOG_PID, LOG_AUTH);

    /* check arguments */
    for (i = 0; i < argc; i++) {
        if (!strcmp(argv[i], "debug"))
            f |= DEBUG;
        else if (!strncmp(argv[i], "-s", 2)) {
            service = strdup(argv[i] + 2);
        } else if (!strncmp(argv[i], "-p", 2)) {
            proxies = add_proxy(proxies, argv[i] + 2);
        } else if (!strncmp(argv[i], "-e", 2)) {
            /* don't let the username pass through if it's excluded */
            if (!strcmp(argv[i] + 2, user)) {
                syslog(LOG_NOTICE, "user '%s' is excluded from the CAS PAM",
                       user);
                free_proxies(proxies);
                return PAM_AUTH_ERR;
            }
        } else
            syslog(LOG_ERR, "invalid option '%s'", argv[i]);
    }

    /* determine the CAS-authenticated username */
    success = cas_validate(pw,
                           service,
                           netid,
                           sizeof(netid),
                           proxies);

    /* free the memory used by the proxy array */
    free_proxies(proxies);

    /* Confirm the user and return appropriately. */
    if ((success == CAS_SUCCESS) && (!strcmp(user, netid))) {
        closelog();
        return PAM_SUCCESS;
    } else {
        syslog(LOG_NOTICE,
               "authentication failure code %d for user '%s'", success, user);
        closelog();
        return PAM_AUTH_ERR;
    }
}
예제 #2
0
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, 
     const char **argv)
{
    pam_cas_config_t *pstConfig = NULL;
    char *configFile = NULL;
    char *user, *pw;
    char *service = NULL;
    char netid[CAS_LEN_NETID];
    int i, success, res, ret;

    /* prepare log */
    openlog("PAM_cas", LOG_PID, LOG_AUTH);

    /* get username and password */
    if (pam_get_user(pamh, (const char**) &user, NULL) != PAM_SUCCESS){
	syslog(LOG_ERR, "Cannot get username");
	END(PAM_AUTH_ERR);
    }
    if (pam_get_item(pamh, PAM_AUTHTOK, (const void**) &pw) != PAM_SUCCESS){
	syslog(LOG_ERR, "Cannot get password (ticket)");
	END(PAM_AUTH_ERR);
    }

   if (!pw)
   {
      if (_get_authtok(pamh) != PAM_SUCCESS){
	 syslog(LOG_ERR, "Cannot get_authtok from pamh");
         END(PAM_AUTH_ERR);
      }
      if (pam_get_item(pamh, PAM_AUTHTOK, (const void**) &pw) != PAM_SUCCESS){
	syslog(LOG_ERR, "Cannot get password (ticket) item from pamh");
	END(PAM_AUTH_ERR);
      }
   }

    /*
     * Abort if the password doesn't look like a ticket.  This speeds things
     * up and reduces the likelihood that the user's password will end up
     * in an HTTPD log.
     */
   if ((strncmp(CAS_BEGIN_PT, pw, strlen(CAS_BEGIN_PT)) != 0)
       && (strncmp(CAS_BEGIN_ST, pw, strlen(CAS_BEGIN_ST)) != 0))
         END(PAM_AUTH_ERR);

    /* check arguments */
    for (i = 0; i < argc; i++) {
        if (!strncmp(argv[i], "-s", 2)) {
	    service = strdup(argv[i] + 2);
	} else if (!strncmp(argv[i], "-f", 2)) {
	    configFile = strdup(argv[i] + 2);
        } else if (!strncmp(argv[i], "-e", 2)) {
	    /* don't let the username pass through if it's excluded */
	    if (!strcmp(argv[i] + 2, user)) {
		syslog(LOG_NOTICE, "user '%s' is excluded from the CAS PAM",
		    user);
		END(PAM_AUTH_ERR);
	    }
	} else
	    syslog(LOG_ERR, "invalid option '%s'", argv[i]);
    }
    res = read_config (configFile, &pstConfig, DEBUG_NO);
    if (res != CAS_SUCCESS)
    {
      syslog(LOG_ERR, "Error with config file %s : %s\n", configFile, ErrorMessage[res]);
      END(PAM_AUTH_ERR);
    }

    /* determine the CAS-authenticated username */
    success = cas_validate(pw, 
                           service, 
                           netid, 
                           sizeof(netid),
			   pstConfig); 


    /* Confirm the user and return appropriately. */
    if ((success == CAS_SUCCESS) && (!strcasecmp(user, netid))) {
	if (pstConfig->debug)
	  syslog(LOG_NOTICE, "USER '%s' AUTHENTICATED WITH CAS PT:%s", user, pw);
        END(PAM_SUCCESS);
    } else {
        if (strcmp(user, netid) && (success == CAS_SUCCESS)) {
            syslog(LOG_NOTICE,
              "authentication failure : PAM login (%s) different from CAS login (%s)", user, netid);
	} else {
          if (pstConfig->debug)
            syslog(LOG_NOTICE,
              "authentication failure for user '%s' : %s. PT=%s", user, ErrorMessage[success],pw);
          else
            syslog(LOG_NOTICE,
              "authentication failure for user '%s' : %s.", user, ErrorMessage[success]);
       }
       END(PAM_AUTH_ERR);
    }

end:
  closelog();
  if (service)
    free(service);
  if (configFile)
    free(configFile);
  //  if (pstConfig)
  //free_config(&pstConfig);
  return ret;
}