You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.7 KiB

// Copyright 2007-2010 Mir Calculate Ltd. http://www.calculate-linux.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <security/pam_modules.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ctype.h>
#include <asm/unistd.h>
#include "keyutils.h"
#define PAM_SM_AUTH
#define MAX_V 30
// if (strcmp(arg, "@t" ) == 0) return KEY_SPEC_THREAD_KEYRING;
// if (strcmp(arg, "@p" ) == 0) return KEY_SPEC_PROCESS_KEYRING;
// if (strcmp(arg, "@s" ) == 0) return KEY_SPEC_SESSION_KEYRING;
// if (strcmp(arg, "@u" ) == 0) return KEY_SPEC_USER_KEYRING;
// if (strcmp(arg, "@us") == 0) return KEY_SPEC_USER_SESSION_KEYRING;
// if (strcmp(arg, "@g" ) == 0) return KEY_SPEC_GROUP_KEYRING;
// if (strcmp(arg, "@a" ) == 0) return KEY_SPEC_REQKEY_AUTH_KEY;
// Authentication function
PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
,int argc, const char **argv)
{
unsigned int ctrl;
int retval;
const char *name, *p;
char *token;
// Get username
retval = pam_get_user(pamh, &name, "login: ");
if (retval!=PAM_SUCCESS) {return PAM_AUTH_ERR;};
// Structure for pam-functions
struct pam_conv *conv;
// Structure for pam-messages
struct pam_message *pmsg[3],msg[3];
// Structure for pam-pesponse
struct pam_response *response;
// Get the function to obtain a password
retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv );
if (retval!=PAM_SUCCESS) {return PAM_AUTH_ERR;}
int flag = 0;
for (ctrl=0; argc-- > 0; ++argv)
{
if (!strcmp(*argv,"use_first_pass"))
{
retval = pam_get_item(pamh,PAM_AUTHTOK,(const void **)&p);
if (retval!=PAM_SUCCESS) {return PAM_AUTH_ERR;};
flag = 1;
};
};
if (flag == 0){
// Initialize the structure for pam-messages
pmsg[0] = &msg[0];
msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
msg[0].msg="Password:";
// Get a pointer to the answer pam
retval = conv->conv(1, ( const struct pam_message ** ) pmsg, &response, conv->appdata_ptr);
if (retval!=PAM_SUCCESS) {return PAM_AUTH_ERR;};
// Get Password
p = response->resp;
};
// Ignore the root user
if (strcmp(name,"root")){
key_serial_t dest;
int ret;
// User id and gid
uid_t uid, gid;
// Get user id and gid
uid = getuid();
gid = getgid();
if (uid==0 && gid==0){
// Get id (user key)
dest = KEY_SPEC_USER_SESSION_KEYRING;
// Write the key in the keystore kernel (space of root)
ret = add_key("user", name, p, strlen(p), dest);
};
}
if (p) {
// Copy password for send to next module
token = strdup(p);
p=NULL;
// Send password to next module
retval = pam_set_item (pamh, PAM_AUTHTOK, (const void *) token);
if (retval == PAM_SUCCESS) {return PAM_SUCCESS;}
}
return PAM_AUTH_ERR;
}
// Empty function, necessary for pam-module
PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
,int argc, const char **argv)
{
return PAM_SUCCESS;
}
#ifdef PAM_STATIC
struct pam_module _pam_unix_auth_modstruct = {
"pam_permit",
pam_sm_authenticate,
pam_sm_setcred,
NULL,
NULL,
NULL,
NULL,
};
#endif