目前,我有一个图形应用程序,有两个级别的访问,操作员和管理员。登录和身份验证都是自制的,我希望将应用程序改为使用PAM。我不知道该怎么做才是对的。
如果我错了,请纠正我,但PAM似乎可以归结为“是”或“否”检查--是的,您可以访问该服务,或者不能访问。没有关于拥有不同级别的访问权限的规定。不过,我需要能够分辨出谁是操作员,谁是管理员,如果可能的话,我希望能够通过PAM严格地做到这一点。
因此,我的想法是设置两个服务,具有两种不同的配置--、用于操作员的/etc/pam.d/pamdemo和用于管理员的/etc/pam.d/pamdemo-admin。然后,我的应用程序将尝试首先对pamdemo-admin进行身份验证,如果这一方法失败,则pamdemo。如果两者都失败,则拒绝访问。我是在正确的轨道上还是我完全偏离轨道了?
下面是我编写的一些示例C代码,作为概念的证明。当我登录时,我不想两次提示用户提供他的凭据。我得到了它,所以它会记住两个pam_start()调用的用户名,但是我不能从应用程序级别访问pam_get_item(PAM_AUTHTOK)来对密码执行相同的缓存。在尝试这样做的过程中,我意识到可能有一种完全不同的方法来做到这一点。我希望这个应用程序能够工作,不管是什么身份验证方法,不管是用户名/密码,还是Kerberos票证或指纹等等。
pam_handle_t *try_login(const char *service, int *retval)
{
static char * username = NULL;
struct pam_conv pam_conversation = { conv, NULL };
pam_handle_t * pamh;
*retval = pam_start(service, username, &pam_conversation, &pamh);
if (*retval == PAM_SUCCESS) *retval = pam_authenticate(pamh, 0);
if (*retval == PAM_SUCCESS) *retval = pam_acct_mgmt (pamh, 0);
if (*retval == PAM_SUCCESS) *retval = pam_open_session(pamh, 0);
if (username == NULL) {
if (pam_get_item(pamh, PAM_USER, (const void **) &username) == PAM_SUCCESS) {
username = strdup(username);
}
}
if (*retval != PAM_SUCCESS) {
fprintf(stderr, "%s: %s\n", service, pam_strerror(pamh, *retval));
pam_end(pamh, *retval);
pamh = NULL;
}
return pamh;
}
int main(void)
{
pam_handle_t *pamh = NULL;
int retval;
const char *service, *username;
if (!pamh) pamh = try_login("pamdemo-admin", &retval);
if (!pamh) pamh = try_login("pamdemo", &retval);
if (!pamh) {
fprintf(stderr, "Access denied.\n");
return 1;
}
pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
pam_get_item(pamh, PAM_USER, (const void **) &username);
printf("Logged into %s as %s.\n", service, username);
pam_close_session(pamh, 0);
pam_end (pamh, retval);
return 0;
}正如所写的,这个演示程序重复了“密码:”提示。我不想让它问两次!
发布于 2009-07-23 04:58:43
我相信一个正确的方法可能是:
发布于 2009-07-23 17:51:04
根据咖啡馆的建议,这是我的解决方案:
#define PAM_CALL(call) \
do { \
if ((retval = (call)) != PAM_SUCCESS) { \
goto pam_error; \
} \
} while (0)
int check_admin_login(const char *user)
{
pam_handle_t * pamh = NULL;
struct pam_conv pam_conversation = { conv, NULL };
int retval;
PAM_CALL(pam_start ("pamdemo-admin", user, &pam_conversation, &pamh));
PAM_CALL(pam_acct_mgmt(pamh, 0));
PAM_CALL(pam_end (pamh, retval));
return 1;
pam_error:
pam_end(pamh, retval);
return 0;
}
int main(void)
{
pam_handle_t * pamh = NULL;
struct pam_conv pam_conversation = { conv, NULL };
int retval;
const char * user;
int is_admin;
PAM_CALL(pam_start ("pamdemo", NULL, &pam_conversation, &pamh));
PAM_CALL(pam_authenticate (pamh, 0));
PAM_CALL(pam_acct_mgmt (pamh, 0));
PAM_CALL(pam_open_session (pamh, 0));
PAM_CALL(pam_get_item (pamh, PAM_USER, (const void **) &user));
is_admin = check_admin_login(user);
printf("Logged in as %s (%s).\n", user, is_admin ? "administrator" : "operator");
PAM_CALL(pam_close_session(pamh, 0));
pam_end (pamh, retval);
return 0;
pam_error:
fprintf(stderr, "%s\n", pam_strerror(pamh, retval));
pam_end(pamh, retval);
return 1;
}发布于 2011-03-17 17:34:15
您只需使用命令“group”或"id“,然后为用户获取组,然后是grep组,如果您首先点击admin,那么它就是管理用户,否则它就是一个演示用户。
groups / id命令(在Linux上测试)也将为非本地用户获取组(例如PAM / LDAP)。
因此,不要对服务进行检查,而是检查用户所属的组。
https://stackoverflow.com/questions/1168552
复制相似问题