示例#1
0
文件: pam_auth.c 项目: dgeo96/src
int pam_setcred(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("pam_setcred called"));

    IF_NO_PAMH("pam_setcred", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    if (! flags) {
	flags = PAM_ESTABLISH_CRED;
    }

    retval = _pam_dispatch(pamh, flags, PAM_SETCRED);

#if HAVE_LIBAUDIT
    retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags);
#endif

    D(("pam_setcred exit"));

    return retval;
}
示例#2
0
int pam_authenticate(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("pam_authenticate called"));

    IF_NO_PAMH("pam_authenticate", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    if (pamh->former.choice == PAM_NOT_STACKED) {
	_pam_sanitize(pamh);
	_pam_start_timer(pamh);    /* we try to make the time for a failure
				      independent of the time it takes to
				      fail */
    }

    retval = _pam_dispatch(pamh, flags, PAM_AUTHENTICATE);

    if (retval != PAM_INCOMPLETE) {
	_pam_sanitize(pamh);
	_pam_await_timer(pamh, retval);   /* if unsuccessful then wait now */
	D(("pam_authenticate exit"));
    } else {
	D(("will resume when ready"));
    }

    return retval;
}
示例#3
0
int pam_close_session(pam_handle_t *pamh, int flags)
{
    D(("called"));

    IF_NO_PAMH("pam_close_session", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    return _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);
}
示例#4
0
int pam_chauthtok(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("called."));

    IF_NO_PAMH("pam_chauthtok", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    /* applications are not allowed to set this flags */
    if (flags & (PAM_PRELIM_CHECK | PAM_UPDATE_AUTHTOK)) {
      pam_syslog (pamh, LOG_ERR,
		  "PAM_PRELIM_CHECK or PAM_UPDATE_AUTHTOK set by application");
      return PAM_SYSTEM_ERR;
    }

    if (pamh->former.choice == PAM_NOT_STACKED) {
	_pam_start_timer(pamh);    /* we try to make the time for a failure
				      independent of the time it takes to
				      fail */
	_pam_sanitize(pamh);
	pamh->former.update = PAM_FALSE;
    }

    /* first call to check if there will be a problem */
    if (pamh->former.update ||
	(retval = _pam_dispatch(pamh, flags|PAM_PRELIM_CHECK,
				PAM_CHAUTHTOK)) == PAM_SUCCESS) {
	D(("completed check ok: former=%d", pamh->former.update));
	pamh->former.update = PAM_TRUE;
	retval = _pam_dispatch(pamh, flags|PAM_UPDATE_AUTHTOK,
			       PAM_CHAUTHTOK);
    }

    /* if we completed we should clean up */
    if (retval != PAM_INCOMPLETE) {
	_pam_sanitize(pamh);
	pamh->former.update = PAM_FALSE;
	_pam_await_timer(pamh, retval);   /* if unsuccessful then wait now */
	D(("pam_chauthtok exit %d - %d", retval, pamh->former.choice));
    } else {
	D(("will resume when ready", retval));
    }

    return retval;
}
示例#5
0
int pam_close_session(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("called"));

    IF_NO_PAMH("pam_close_session", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);

#if HAVE_LIBAUDIT
    retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags);
#endif

#ifdef PAM_STATS
	if (retval != PAM_SUCCESS) {
		
        char usr[MAX_PAM_STATS_USR_SIZE];
		char buf[MAX_PAM_STATS_BUF_SIZE];

		usr[MAX_PAM_STATS_USR_SIZE-1]='\0';
		strncpy(usr,(retval == PAM_USER_UNKNOWN)?"unknown":pamh->user,
				MAX_PAM_STATS_USR_SIZE-1);
		memset(buf,'\0',MAX_PAM_STATS_BUF_SIZE);

		snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
				"statsd -a incr pam_failed_%s %s \\;"
				         " push pam_last_failure_%s %s \"%s\" 0 \\;"
				         " incr pam_users %s\\;"
				         " incr pam_services %s",
				usr, pamh->service_name,
				usr, pamh->service_name, pam_strerror(pamh, retval),
				usr,
				pamh->service_name);
		
		if (system(buf) == -1) {
			pam_syslog(pamh, LOG_INFO, "%s - failed", buf);
		}
	}
#endif

    return retval;

}
示例#6
0
int pam_open_session(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("called"));

    IF_NO_PAMH("pam_open_session", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }
    retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION);

    return retval;
}
示例#7
0
int pam_acct_mgmt(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("called"));

    IF_NO_PAMH("pam_acct_mgmt", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT);

#ifdef HAVE_LIBAUDIT
    retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags);
#endif

    return retval;
}
示例#8
0
int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
{
    int retval;

    D(("called"));

    IF_NO_PAMH("pam_set_item", pamh, PAM_SYSTEM_ERR);
    
    retval = PAM_SUCCESS;

    switch (item_type) {

    case PAM_SERVICE:
	/* Setting handlers_loaded to 0 will cause the handlers
	 * to be reloaded on the next call to a service module.
	 */
	pamh->handlers.handlers_loaded = 0;
	RESET(pamh->service_name, item);
	{
	    char *tmp;
	    for (tmp=pamh->service_name; *tmp; ++tmp)
		*tmp = tolower(*tmp);                 /* require lower case */
	}
	break;

    case PAM_USER:
	RESET(pamh->user, item);
	break;

    case PAM_USER_PROMPT:
	RESET(pamh->prompt, item);
	break;

    case PAM_TTY:
	D(("setting tty to %s", item));
	RESET(pamh->tty, item);
	break;

    case PAM_RUSER:
	RESET(pamh->ruser, item);
	break;

    case PAM_RHOST:
	RESET(pamh->rhost, item);
	break;

    case PAM_AUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    char *_TMP_ = pamh->authtok;
	    if (_TMP_ == item)            /* not changed so leave alone */
		break;
	    pamh->authtok = (item) ? _pam_strdup(item) : NULL;
	    if (_TMP_) {
		_pam_overwrite(_TMP_);
		free(_TMP_);
	    }
	} else {
	    retval = PAM_BAD_ITEM;
	}

	break;

    case PAM_OLDAUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    char *_TMP_ = pamh->oldauthtok;
	    if (_TMP_ == item)            /* not changed so leave alone */
		break;
	    pamh->oldauthtok = (item) ? _pam_strdup(item) : NULL;
	    if (_TMP_) {
		_pam_overwrite(_TMP_);
		free(_TMP_);
	    }
	} else {
	    retval = PAM_BAD_ITEM;
	}

	break;

    case PAM_CONV:              /* want to change the conversation function */
	if (item == NULL) {
	    _pam_system_log(LOG_ERR,
			    "pam_set_item: attempt to set conv() to NULL");
	    retval = PAM_PERM_DENIED;
	} else {
	    struct pam_conv *tconv;
	    
	    if ((tconv=
		 (struct pam_conv *) malloc(sizeof(struct pam_conv))
		) == NULL) {
		_pam_system_log(LOG_CRIT,
				"pam_set_item: malloc failed for pam_conv");
		retval = PAM_BUF_ERR;
	    } else {
		memcpy(tconv, item, sizeof(struct pam_conv));
		_pam_drop(pamh->pam_conversation);
		pamh->pam_conversation = tconv;
	    }
	}
        break;

    case PAM_FAIL_DELAY:
	pamh->fail_delay.delay_fn_ptr = item;
	break;

    default:
	retval = PAM_BAD_ITEM;
    }

    return retval;
}
示例#9
0
int pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
{
    int retval = PAM_SUCCESS;

    D(("called."));
    IF_NO_PAMH("pam_get_item", pamh, PAM_SYSTEM_ERR);

    if (item == NULL) {
	_pam_system_log(LOG_ERR,
			"pam_get_item: nowhere to place requested item");
	return PAM_PERM_DENIED;
    }

    switch (item_type) {
    case PAM_SERVICE:
	*item = pamh->service_name;
	break;

    case PAM_USER:
	D(("returning user=%s", pamh->user));
	*item = pamh->user;
	break;

    case PAM_USER_PROMPT:
	D(("returning userprompt=%s", pamh->user));
	*item = pamh->prompt;
	break;

    case PAM_TTY:
	D(("returning tty=%s", pamh->tty));
	*item = pamh->tty;
	break;

    case PAM_RUSER:
	*item = pamh->ruser;
	break;

    case PAM_RHOST:
	*item = pamh->rhost;
	break;

    case PAM_AUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    *item = pamh->authtok;
	} else {
	    retval = PAM_BAD_ITEM;
	}
	break;

    case PAM_OLDAUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    *item = pamh->oldauthtok;
	} else {
	    retval = PAM_BAD_ITEM;
	}
	break;

    case PAM_CONV:
	*item = pamh->pam_conversation;
	break;

    case PAM_FAIL_DELAY:
	*item = pamh->fail_delay.delay_fn_ptr;
	break;

    default:
	retval = PAM_BAD_ITEM;
    }
  
    return retval;
}
示例#10
0
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
    struct handler *h = NULL;
    int retval = PAM_SYSTEM_ERR, use_cached_chain;
    _pam_boolean resumed;

    IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from a module!?"));
	goto end;
    }

    /* Load all modules, resolve all symbols */

    if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
	pam_syslog(pamh, LOG_ERR, "unable to dispatch function");
	goto end;
    }

    use_cached_chain = _PAM_PLEASE_FREEZE;

    switch (choice) {
    case PAM_AUTHENTICATE:
	h = pamh->handlers.conf.authenticate;
	break;
    case PAM_SETCRED:
	h = pamh->handlers.conf.setcred;
	use_cached_chain = _PAM_MAY_BE_FROZEN;
	break;
    case PAM_ACCOUNT:
	h = pamh->handlers.conf.acct_mgmt;
	break;
    case PAM_OPEN_SESSION:
	h = pamh->handlers.conf.open_session;
	break;
    case PAM_CLOSE_SESSION:
	h = pamh->handlers.conf.close_session;
	use_cached_chain = _PAM_MAY_BE_FROZEN;
	break;
    case PAM_CHAUTHTOK:
	h = pamh->handlers.conf.chauthtok;
	break;
    default:
	pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice);
	retval = PAM_ABORT;
	goto end;
    }

    if (h == NULL) {     /* there was no handlers.conf... entry; will use
			  * handlers.other... */
	switch (choice) {
	case PAM_AUTHENTICATE:
	    h = pamh->handlers.other.authenticate;
	    break;
	case PAM_SETCRED:
	    h = pamh->handlers.other.setcred;
	    break;
	case PAM_ACCOUNT:
	    h = pamh->handlers.other.acct_mgmt;
	    break;
	case PAM_OPEN_SESSION:
	    h = pamh->handlers.other.open_session;
	    break;
	case PAM_CLOSE_SESSION:
	    h = pamh->handlers.other.close_session;
	    break;
	case PAM_CHAUTHTOK:
	    h = pamh->handlers.other.chauthtok;
	    break;
	}
    }

    /* Did a module return an "incomplete state" last time? */
    if (pamh->former.choice != PAM_NOT_STACKED) {
	if (pamh->former.choice != choice) {
	    pam_syslog(pamh, LOG_ERR,
			    "application failed to re-exec stack [%d:%d]",
			    pamh->former.choice, choice);
	    retval = PAM_ABORT;
	    goto end;
	}
	resumed = PAM_TRUE;
    } else {
	resumed = PAM_FALSE;
	_pam_clear_grantors(h);
    }

    __PAM_TO_MODULE(pamh);

    /* call the list of module functions */
    pamh->choice = choice;
    retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain);
    resumed = PAM_FALSE;

    __PAM_TO_APP(pamh);

    /* Should we recall where to resume next time? */
    if (retval == PAM_INCOMPLETE) {
	D(("module [%d] returned PAM_INCOMPLETE"));
	pamh->former.choice = choice;
    } else {
	pamh->former.choice = PAM_NOT_STACKED;
    }

end:

#ifdef HAVE_LIBAUDIT
    if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) {
	retval = _pam_auditlog(pamh, choice, retval, flags, h);
    }
#endif

    return retval;
}
示例#11
0
int pam_end(pam_handle_t *pamh, int pam_status)
{
    int ret;

    D(("entering pam_end()"));

    IF_NO_PAMH("pam_end", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    /* first liberate the modules (it is not inconcevible that the
       modules may need to use the service_name etc. to clean up) */

    _pam_free_data(pamh, pam_status);

    /* now drop all modules */

    if ((ret = _pam_free_handlers(pamh)) != PAM_SUCCESS) {
	return ret;                 /* error occurred */
    }

    /* from this point we cannot call the modules any more. Free the remaining
       memory used by the Linux-PAM interface */

    _pam_drop_env(pamh);                      /* purge the environment */

    _pam_overwrite(pamh->authtok);            /* blank out old token */
    _pam_drop(pamh->authtok);

    _pam_overwrite(pamh->oldauthtok);         /* blank out old token */
    _pam_drop(pamh->oldauthtok);

    _pam_overwrite(pamh->former.prompt);
    _pam_drop(pamh->former.prompt);           /* drop saved prompt */

    _pam_overwrite(pamh->service_name);
    _pam_drop(pamh->service_name);

    _pam_overwrite(pamh->user);
    _pam_drop(pamh->user);

    _pam_overwrite(pamh->prompt);
    _pam_drop(pamh->prompt);                  /* prompt for pam_get_user() */

    _pam_overwrite(pamh->tty);
    _pam_drop(pamh->tty);

    _pam_overwrite(pamh->rhost);
    _pam_drop(pamh->rhost);

    _pam_overwrite(pamh->ruser);
    _pam_drop(pamh->ruser);

    _pam_drop(pamh->pam_conversation);
    pamh->fail_delay.delay_fn_ptr = NULL;

    /* and finally liberate the memory for the pam_handle structure */

    _pam_drop(pamh);

    D(("exiting pam_end() successfully"));

    return PAM_SUCCESS;
}
示例#12
0
文件: pam_auth.c 项目: dgeo96/src
int pam_authenticate(pam_handle_t *pamh, int flags)
{
    int retval;

    D(("pam_authenticate called"));

    IF_NO_PAMH("pam_authenticate", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

    if (pamh->former.choice == PAM_NOT_STACKED) {
	_pam_sanitize(pamh);
	_pam_start_timer(pamh);    /* we try to make the time for a failure
				      independent of the time it takes to
				      fail */
    }

    retval = _pam_dispatch(pamh, flags, PAM_AUTHENTICATE);

    if (retval != PAM_INCOMPLETE) {
	_pam_sanitize(pamh);
	_pam_await_timer(pamh, retval);   /* if unsuccessful then wait now */
	D(("pam_authenticate exit"));
    } else {
	D(("will resume when ready"));
    }
    	
#ifdef PRELUDE
    prelude_send_alert(pamh, retval);
#endif
     	
#if HAVE_LIBAUDIT
    retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags);
#endif

#ifdef CONFIG_PROP_STATSD_STATSD
	if (retval != PAM_SUCCESS) {

        char usr[MAX_PAM_STATS_USR_SIZE];
		char buf[MAX_PAM_STATS_BUF_SIZE]; 
		struct pam_data *data;
        char *u = NULL;

		/* The pam_sg module has stored module data so we 
		 * can tell whether this is a valid user. If not
		 * we log stats under "unknown". The proper mechanism
		 * for accessing module data bars access from within 
		 * application code so we are going around it. This is 
		 * a kludge, but the best one possible for now.
		 */
		data = pamh->data;
		while (data) {
			if (!strcmp(data->name, pamh->user)) {
				u = (char *)(data->data);
				break;
			}
			data = data->next;
		}

		/* Don't log stats if the module info is unavailable
		 * or the PAM system itself failed during auth */
		if ((u != NULL) && strcmp(u, "PAM_SYSTEM_ERR")) {

			u = ((u != NULL) && !strcmp(u, "PAM_USER_UNKNOWN")) ? "unknown":pamh->user;
			//u = ((u != NULL) && !strcmp(u, "USER_NOTFOUND")) ? "unknown":pamh->user;

			usr[MAX_PAM_STATS_USR_SIZE-1]='\0';
			strncpy(usr,u,MAX_PAM_STATS_USR_SIZE-1);

			/* OK, start logging stats */
			memset(buf,'\0',MAX_PAM_STATS_BUF_SIZE);

			snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
					"statsd incr pam_failed_%s %s",
					usr,pamh->service_name);

			if (system(buf) == -1) {
				pam_syslog(pamh, LOG_INFO, "%s failed", buf);
			}

			snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
					"statsd push pam_last_failure_%s %s \"%s\" 0",
					usr,pamh->service_name, pam_strerror(pamh, retval));

			if (system(buf) == -1) {
				pam_syslog(pamh, LOG_INFO, "%s failed", buf);
			}

			snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
					"statsd incr pam_users %s",usr);

			if (system(buf) == -1) {
				pam_syslog(pamh, LOG_INFO, "%s - failed", buf);
			}

			snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
					"statsd incr pam_services %s",pamh->service_name);

			if (system(buf) == -1) {
				pam_syslog(pamh, LOG_INFO, "%s - failed", buf);
			}
		} 
	}
#endif

    return retval;
}
示例#13
0
文件: pam_end.c 项目: dgeo96/src
int pam_end(pam_handle_t *pamh, int pam_status)
{
    int ret;

    D(("entering pam_end()"));

    IF_NO_PAMH("pam_end", pamh, PAM_SYSTEM_ERR);

    if (__PAM_FROM_MODULE(pamh)) {
	D(("called from module!?"));
	return PAM_SYSTEM_ERR;
    }

#ifdef HAVE_LIBAUDIT
    _pam_audit_end(pamh, pam_status);
#endif

#ifdef CONFIG_PROP_STATSD_STATSD
	if (pam_status == PAM_SUCCESS) {

		char buf[MAX_PAM_STATS_BUF_SIZE];
		memset(buf,'\0',MAX_PAM_STATS_BUF_SIZE);

		snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
				"statsd incr pam_succeeded_%s %s",
				pamh->user,pamh->service_name);

		if (system(buf) == -1) {
			pam_syslog(pamh, LOG_INFO, "%s %s statsd incr failed",
						buf, pamh->service_name);
		}

		snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
				"statsd incr pam_users %s", pamh->user);

		if (system(buf) == -1) {
			pam_syslog(pamh, LOG_INFO, "%s - failed", buf);
		}

		snprintf(buf, MAX_PAM_STATS_BUF_SIZE-1,
				"statsd incr pam_services %s", pamh->service_name);

		if (system(buf) == -1) {
			pam_syslog(pamh, LOG_INFO, "%s - failed", buf);
		}
	}
#endif

    /* first liberate the modules (it is not inconcevible that the
       modules may need to use the service_name etc. to clean up) */

    _pam_free_data(pamh, pam_status);

    /* now drop all modules */

    if ((ret = _pam_free_handlers(pamh)) != PAM_SUCCESS) {
	return ret;                 /* error occurred */
    }

    /* from this point we cannot call the modules any more. Free the remaining
       memory used by the Linux-PAM interface */

    _pam_drop_env(pamh);                      /* purge the environment */

    _pam_overwrite(pamh->authtok);            /* blank out old token */
    _pam_drop(pamh->authtok);

    _pam_overwrite(pamh->oldauthtok);         /* blank out old token */
    _pam_drop(pamh->oldauthtok);

    _pam_overwrite(pamh->former.prompt);
    _pam_drop(pamh->former.prompt);           /* drop saved prompt */

    _pam_overwrite(pamh->service_name);
    _pam_drop(pamh->service_name);

    _pam_overwrite(pamh->user);
    _pam_drop(pamh->user);

    _pam_overwrite(pamh->prompt);
    _pam_drop(pamh->prompt);                  /* prompt for pam_get_user() */

    _pam_overwrite(pamh->tty);
    _pam_drop(pamh->tty);

    _pam_overwrite(pamh->rhost);
    _pam_drop(pamh->rhost);

    _pam_overwrite(pamh->ruser);
    _pam_drop(pamh->ruser);

    _pam_drop(pamh->pam_conversation);
    pamh->fail_delay.delay_fn_ptr = NULL;

    /* and finally liberate the memory for the pam_handle structure */

    _pam_drop(pamh);

    D(("exiting pam_end() successfully"));

    return PAM_SUCCESS;
}
示例#14
0
int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
{
    int retval;

    D(("called"));

    IF_NO_PAMH("pam_set_item", pamh, PAM_SYSTEM_ERR);

    retval = PAM_SUCCESS;

    switch (item_type) {

    case PAM_SERVICE:
	/* Setting handlers_loaded to 0 will cause the handlers
	 * to be reloaded on the next call to a service module.
	 */
	pamh->handlers.handlers_loaded = 0;
	TRY_SET(pamh->service_name, item);
	{
	    char *tmp;
	    for (tmp=pamh->service_name; *tmp; ++tmp)
		*tmp = tolower(*tmp);                 /* require lower case */
	}
	break;

    case PAM_USER:
	TRY_SET(pamh->user, item);
	pamh->former.fail_user = PAM_SUCCESS;
	break;

    case PAM_USER_PROMPT:
	TRY_SET(pamh->prompt, item);
	pamh->former.fail_user = PAM_SUCCESS;
	break;

    case PAM_TTY:
	D(("setting tty to %s", item));
	TRY_SET(pamh->tty, item);
	break;

    case PAM_RUSER:
	TRY_SET(pamh->ruser, item);
	break;

    case PAM_RHOST:
	TRY_SET(pamh->rhost, item);
	break;

    case PAM_AUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    if (pamh->authtok != item) {
		_pam_overwrite(pamh->authtok);
		TRY_SET(pamh->authtok, item);
	    }
	} else {
	    retval = PAM_BAD_ITEM;
	}

	break;

    case PAM_OLDAUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    if (pamh->oldauthtok != item) {
		_pam_overwrite(pamh->oldauthtok);
		TRY_SET(pamh->oldauthtok, item);
	    }
	} else {
	    retval = PAM_BAD_ITEM;
	}

	break;

    case PAM_CONV:              /* want to change the conversation function */
	if (item == NULL) {
	    pam_syslog(pamh, LOG_ERR,
		       "pam_set_item: attempt to set conv() to NULL");
	    retval = PAM_PERM_DENIED;
	} else {
	    struct pam_conv *tconv;

	    if ((tconv=
		 (struct pam_conv *) malloc(sizeof(struct pam_conv))
		) == NULL) {
		pam_syslog(pamh, LOG_CRIT,
				"pam_set_item: malloc failed for pam_conv");
		retval = PAM_BUF_ERR;
	    } else {
		memcpy(tconv, item, sizeof(struct pam_conv));
		_pam_drop(pamh->pam_conversation);
		pamh->pam_conversation = tconv;
		pamh->former.fail_user = PAM_SUCCESS;
	    }
	}
        break;

    case PAM_FAIL_DELAY:
	pamh->fail_delay.delay_fn_ptr = item;
	break;

    case PAM_XDISPLAY:
	TRY_SET(pamh->xdisplay, item);
	break;

    case PAM_XAUTHDATA:
	if (&pamh->xauth == item)
	    break;
	if (pamh->xauth.namelen) {
	    _pam_overwrite(pamh->xauth.name);
	    free(pamh->xauth.name);
	}
	if (pamh->xauth.datalen) {
	    _pam_overwrite_n(pamh->xauth.data,
			   (unsigned int) pamh->xauth.datalen);
	    free(pamh->xauth.data);
	}
	pamh->xauth = *((const struct pam_xauth_data *) item);
	if ((pamh->xauth.name=_pam_strdup(pamh->xauth.name)) == NULL) {
	    memset(&pamh->xauth, '\0', sizeof(pamh->xauth));
	    return PAM_BUF_ERR;
	}	
	if ((pamh->xauth.data=_pam_memdup(pamh->xauth.data,
	    pamh->xauth.datalen)) == NULL) {
	    _pam_overwrite(pamh->xauth.name);
	    free(pamh->xauth.name);
	    memset(&pamh->xauth, '\0', sizeof(pamh->xauth));
	    return PAM_BUF_ERR;
	}
	break;

    /* begin: add by yangguang */
    default:
        if (item_type > PAM_EXT_BASE)
        {
            retval = pam_set_extern_item_value (pamh, item_type, item);
        }
        else
        {
            retval = PAM_BAD_ITEM;
        }
    }/* end switch */

    /* end: add by yangguang */
    return retval;
}
示例#15
0
int pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
{
    int retval = PAM_SUCCESS;

    D(("called."));
    IF_NO_PAMH("pam_get_item", pamh, PAM_SYSTEM_ERR);

    if (item == NULL) {
	pam_syslog(pamh, LOG_ERR,
			"pam_get_item: nowhere to place requested item");
	return PAM_PERM_DENIED;
    }
    else
	*item = NULL;

    switch (item_type) {
    case PAM_SERVICE:
	*item = pamh->service_name;
	break;

    case PAM_USER:
	D(("returning user=%s", pamh->user));
	*item = pamh->user;
	break;

    case PAM_USER_PROMPT:
	D(("returning userprompt=%s", pamh->user));
	*item = pamh->prompt;
	break;

    case PAM_TTY:
	D(("returning tty=%s", pamh->tty));
	*item = pamh->tty;
	break;

    case PAM_RUSER:
	*item = pamh->ruser;
	break;

    case PAM_RHOST:
	*item = pamh->rhost;
	break;

    case PAM_AUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    *item = pamh->authtok;
	} else {
	    retval = PAM_BAD_ITEM;
	}
	break;

    case PAM_OLDAUTHTOK:
	/*
	 * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
	 * modules.
	 */
	if (__PAM_FROM_MODULE(pamh)) {
	    *item = pamh->oldauthtok;
	} else {
	    retval = PAM_BAD_ITEM;
	}
	break;

    case PAM_CONV:
	*item = pamh->pam_conversation;
	break;

    case PAM_FAIL_DELAY:
	*item = pamh->fail_delay.delay_fn_ptr;
	break;

    case PAM_XDISPLAY:
	*item = pamh->xdisplay;
	break;

    case PAM_XAUTHDATA:
	*item = &pamh->xauth;
	break;

    /* begin: add by yangguang */
    default:
        if (item_type > PAM_EXT_BASE)
        {
            retval = pam_get_extern_item_value (pamh, item_type, item);
        }
        else
        {
            retval = PAM_BAD_ITEM;
        }
    /* end: add by yangguang */
    }/* end switch */

    return retval;
}