Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
48
cde/lib/pam/pam_modules/dce/Imakefile
Normal file
48
cde/lib/pam/pam_modules/dce/Imakefile
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $XConsortium: Imakefile /main/4 1996/04/21 19:13:14 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1996 International Business Machines Corp.
|
||||
* (c) Copyright 1995,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#define DoNormalLib NormalLibPam
|
||||
#define DoSharedLib SharedLibPam
|
||||
#define DoDebugLib DebugLibPam
|
||||
#define DoProfileLib ProfileLibPam
|
||||
#define LibName pam_dce
|
||||
#define SoRev SOPAMREV
|
||||
#define LibHeaders NO
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
SRCS = \
|
||||
dce_authenticate.c \
|
||||
dce_setcred.c \
|
||||
dce_acct_mgmt.c \
|
||||
dce_password.c \
|
||||
dce_session.c \
|
||||
utils.c \
|
||||
xfn_mapping.c
|
||||
|
||||
OBJS = \
|
||||
dce_authenticate.o \
|
||||
dce_setcred.o \
|
||||
dce_acct_mgmt.o \
|
||||
dce_password.o \
|
||||
dce_session.o \
|
||||
utils.o \
|
||||
xfn_mapping.o
|
||||
|
||||
#ifdef SharedPamDceAuthReqs
|
||||
REQUIREDLIBS = SharedPamDceAuthReqs
|
||||
#endif
|
||||
|
||||
INCLUDES = -I../../libpam
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
DependTarget()
|
||||
179
cde/lib/pam/pam_modules/dce/dce_acct_mgmt.c
Normal file
179
cde/lib/pam/pam_modules/dce/dce_acct_mgmt.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/* $XConsortium: dce_acct_mgmt.c /main/5 1996/05/09 04:26:10 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)dce_acct_mgmt.c 1.3 95/08/02 SMI"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <libintl.h>
|
||||
#include <dce/sec_login.h>
|
||||
#include <dce/dce_error.h>
|
||||
|
||||
#include "pam_impl.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
* pam_sm_acct_mgmt main account managment routine.
|
||||
* XXX: The routine just prints out a warning message.
|
||||
* It may need to force the user to change his/her
|
||||
* passwd.
|
||||
*/
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#define SECS_PER_HOUR (60*60)
|
||||
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
|
||||
|
||||
static void
|
||||
do_warn(pam_handle_t *pamh, time_t cur, time_t t, char *desc);
|
||||
|
||||
static void
|
||||
do_warn_passwd(pam_handle_t *pamh);
|
||||
|
||||
int
|
||||
pam_sm_acct_mgmt(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
dce_module_data_t *dsd;
|
||||
sec_login_net_info_t net_info;
|
||||
error_status_t st;
|
||||
time_t curtime;
|
||||
int result = PAM_AUTH_ERR;
|
||||
int i, debug = 0;
|
||||
int warn = 1;
|
||||
int allow_expired_passwd = 0;
|
||||
int err;
|
||||
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "allow_expired_passwd") == 0)
|
||||
allow_expired_passwd = 1;
|
||||
else if (strcmp(argv[i], "nowarn") == 0)
|
||||
warn = 0;
|
||||
else
|
||||
syslog(LOG_ERR,
|
||||
"illegal DCE acct_mgmt option %s", argv[i]);
|
||||
}
|
||||
|
||||
if (flags & PAM_SILENT) warn = 0;
|
||||
|
||||
if (debug) syslog(LOG_DEBUG, "DCE pam_sm_acct_mgmt");
|
||||
|
||||
if (pam_get_data(pamh, DCE_DATA, (void**)&dsd) != PAM_SUCCESS ||
|
||||
dsd == NULL) {
|
||||
return (PAM_AUTH_ERR);
|
||||
}
|
||||
|
||||
if (dsd->auth_status != PAM_SUCCESS)
|
||||
return (dsd->auth_status);
|
||||
|
||||
if (dsd->auth_src == sec_login_auth_src_local) {
|
||||
/* we can't call sec_login_inquire_net_info on locally */
|
||||
/* authenticated contexts. Might want an option to dis-allow */
|
||||
/* them. For now we just allow them. */
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
|
||||
sec_login_inquire_net_info(dsd->login_context, &net_info, &st);
|
||||
|
||||
if (st != error_status_ok && st != sec_login_s_not_certified) {
|
||||
if (debug) {
|
||||
dce_error_string_t text;
|
||||
|
||||
syslog(LOG_DEBUG, "sec_login_inquire_net_info: %s",
|
||||
get_dce_error_message(st, text));
|
||||
}
|
||||
return (PAM_PERM_DENIED);
|
||||
}
|
||||
|
||||
time(&curtime);
|
||||
|
||||
if (warn) {
|
||||
if (dsd->reset_passwd) {
|
||||
do_warn_passwd(pamh);
|
||||
} else {
|
||||
do_warn(pamh, curtime,
|
||||
(time_t) net_info.passwd_expiration_date,
|
||||
"passwd");
|
||||
}
|
||||
}
|
||||
|
||||
if (warn) do_warn(pamh, curtime,
|
||||
(time_t) net_info.acct_expiration_date, "account");
|
||||
|
||||
result = PAM_SUCCESS;
|
||||
|
||||
if ((net_info.passwd_expiration_date &&
|
||||
net_info.passwd_expiration_date < curtime) ||
|
||||
dsd->reset_passwd) {
|
||||
|
||||
result = PAM_AUTHTOKEN_REQD;
|
||||
|
||||
dsd->passwd_expired = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* I assume an expired account is worse then an expired password,
|
||||
* so if both the password and account are expired we want to
|
||||
* return PAM_ACCT_EXPIRED.
|
||||
*/
|
||||
|
||||
if (net_info.acct_expiration_date &&
|
||||
net_info.acct_expiration_date < curtime) {
|
||||
result = PAM_ACCT_EXPIRED;
|
||||
}
|
||||
|
||||
sec_login_free_net_info(&net_info);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
do_warn(pam_handle_t *pamh, time_t cur, time_t t, char *desc)
|
||||
{
|
||||
char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
|
||||
|
||||
if (t == 0)
|
||||
return; /* unlimited */
|
||||
|
||||
if (cur > t) {
|
||||
sprintf(messages[0],
|
||||
PAM_MSG(pamh, 1, "Warning: Your DCE %s has expired.\n"), desc);
|
||||
} else if ((cur + SECS_PER_DAY) > t) {
|
||||
int hours;
|
||||
|
||||
hours = (t - cur) / (SECS_PER_HOUR);
|
||||
hours = hours ? hours : 1;
|
||||
sprintf(messages[0], PAM_MSG(pamh, 2,
|
||||
"Warning: Your DCE %s will expire within %d hour%s.\n"),
|
||||
desc, hours, (hours == 1) ? "" : "s");
|
||||
} else if ((cur + (2*SECS_PER_DAY)) > t) {
|
||||
sprintf(messages[0], PAM_MSG(pamh, 3,
|
||||
"Warning: Your DCE %s will expire in 2 days.\n"), desc);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
__pam_display_msg(pamh, PAM_ERROR_MSG, 1, messages, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_warn_passwd(pam_handle_t *pamh)
|
||||
{
|
||||
char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
|
||||
|
||||
sprintf(messages[0],
|
||||
PAM_MSG(pamh, 4, "Warning: Your DCE passwd has expired.\n"));
|
||||
|
||||
__pam_display_msg(pamh, PAM_ERROR_MSG, 1, messages, NULL);
|
||||
}
|
||||
434
cde/lib/pam/pam_modules/dce/dce_authenticate.c
Normal file
434
cde/lib/pam/pam_modules/dce/dce_authenticate.c
Normal file
@@ -0,0 +1,434 @@
|
||||
/* $XConsortium: dce_authenticate.c /main/5 1996/05/09 04:26:26 drk $ */
|
||||
/*
|
||||
* Copyright (c) 1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)dce_authenticate.c 1.34 96/02/14 SMI"
|
||||
|
||||
#include <dce/nbase.h>
|
||||
#include <dce/sec_login.h>
|
||||
#include <dce/dce_error.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <rpc/des_crypt.h>
|
||||
#include <pwd.h>
|
||||
#include <syslog.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include "pam_impl.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
#include "xfn_mapping.h"
|
||||
#endif /* XFN_MAPPING */
|
||||
|
||||
#define SLEEPTIME 4
|
||||
|
||||
/* maxmimum DCE_PASSWD_LENGTH. We need to pick something for
|
||||
* __pam_get_authtok to use.
|
||||
*/
|
||||
|
||||
#define DCE_PASSWD_LENGTH 256
|
||||
|
||||
static int
|
||||
attempt_dce_login(
|
||||
void *pamh,
|
||||
dce_module_data_t *dsd,
|
||||
error_status_t *st,
|
||||
char *user,
|
||||
char *dce_pass
|
||||
);
|
||||
|
||||
void
|
||||
dce_cleanup(
|
||||
pam_handle_t *pamh,
|
||||
void *data,
|
||||
int pam_status
|
||||
);
|
||||
|
||||
/*
|
||||
* pam_sm_authenticate - Authenticate user
|
||||
*/
|
||||
|
||||
int
|
||||
pam_sm_authenticate(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
char *user;
|
||||
int err, result = PAM_AUTH_ERR;
|
||||
char messages[1][PAM_MAX_MSG_SIZE];
|
||||
error_status_t st;
|
||||
char *defpass;
|
||||
int num_msg = 0;
|
||||
int debug = 0;
|
||||
int warn = 1;
|
||||
int passwd_flag = 0;
|
||||
int try_first_pass = 0;
|
||||
int use_first_pass = 0;
|
||||
int ignore = 0;
|
||||
int invalid_user = 0;
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
int try_mapped_pass = 0;
|
||||
int use_mapped_pass = 0;
|
||||
#endif
|
||||
int i;
|
||||
char *firstpass = NULL, *password = NULL;
|
||||
uid_t pw_uid;
|
||||
dce_module_data_t *dsd = NULL;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "try_first_pass") == 0) {
|
||||
if (!passwd_flag) {
|
||||
try_first_pass = 1;
|
||||
passwd_flag = 1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "use_first_pass") == 0) {
|
||||
if (!passwd_flag) {
|
||||
use_first_pass = 1;
|
||||
passwd_flag = 1;
|
||||
}
|
||||
#ifdef XFN_MAPPING
|
||||
} else if (strcmp(argv[i], "try_mapped_pass") == 0) {
|
||||
if (!passwd_flag) {
|
||||
try_mapped_pass = 1;
|
||||
passwd_flag = 1;
|
||||
}
|
||||
} else if (strcmp(argv[i], "use_mapped_pass") == 0) {
|
||||
if (!passwd_flag) {
|
||||
use_mapped_pass = 1;
|
||||
passwd_flag = 1;
|
||||
}
|
||||
#endif
|
||||
} else if (strcmp(argv[i], "nowarn") == 0) {
|
||||
warn = 0;
|
||||
} else {
|
||||
syslog(LOG_ERR, "illegal module option %s", argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & PAM_SILENT) warn = 0;
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "DCE pam_sm_authenticate");
|
||||
|
||||
err = pam_get_user(pamh, &user, NULL);
|
||||
|
||||
if (err != PAM_SUCCESS)
|
||||
return (err);
|
||||
|
||||
if (user == NULL || !user[0])
|
||||
return (PAM_AUTH_ERR);
|
||||
|
||||
/* Don't bother to authenticate root in DCE */
|
||||
|
||||
if (strcmp(user, "root") == 0)
|
||||
ignore = 1;
|
||||
|
||||
/* make sure a password entry exists for this user */
|
||||
/* we also need the uid for XFN */
|
||||
|
||||
if (!get_pw_uid(user, &pw_uid)) {
|
||||
invalid_user = 1;
|
||||
}
|
||||
|
||||
if (pam_get_data(pamh, DCE_DATA, (void**)&dsd) != PAM_SUCCESS ||
|
||||
dsd == NULL) {
|
||||
|
||||
dsd = calloc(1, sizeof (dce_module_data_t));
|
||||
if (dsd == NULL) {
|
||||
result = PAM_BUF_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((err = pam_set_data(pamh, DCE_DATA, dsd, &dce_cleanup))
|
||||
!= PAM_SUCCESS) {
|
||||
free(dsd);
|
||||
result = err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (dsd->login_context != sec_login_default_handle) {
|
||||
error_status_t st;
|
||||
sec_login_purge_context(&dsd->login_context, &st);
|
||||
}
|
||||
}
|
||||
|
||||
dsd->login_context = sec_login_default_handle;
|
||||
dsd->auth_status = PAM_AUTH_ERR;
|
||||
dsd->debug = debug;
|
||||
dsd->warn = warn;
|
||||
dsd->reset_passwd = 0;
|
||||
dsd->passwd_expired = 0;
|
||||
dsd->auth_src = sec_login_auth_src_network;
|
||||
|
||||
/* see if a legitimate DCE user */
|
||||
|
||||
if (!sec_login_setup_identity((unsigned char *)user,
|
||||
sec_login_no_flags, &dsd->login_context, &st)) {
|
||||
if (debug) {
|
||||
dce_error_string_t text;
|
||||
syslog(LOG_DEBUG,
|
||||
"PAM: DCE sec_login_setup_identity: %s",
|
||||
get_dce_error_message(st, text));
|
||||
}
|
||||
if (st == sec_rgy_object_not_found) {
|
||||
/* mask the unknown user case */
|
||||
invalid_user = 1;
|
||||
} else {
|
||||
result = PAM_AUTH_ERR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
err = pam_get_item(pamh, PAM_AUTHTOK, (void **) &firstpass);
|
||||
|
||||
if (err != PAM_SUCCESS && (use_first_pass || use_mapped_pass)) {
|
||||
result = PAM_AUTH_ERR;
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "PAM: DCE goto out!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (firstpass != NULL && (ignore || invalid_user))
|
||||
goto out;
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
|
||||
if (firstpass == NULL) {
|
||||
if (use_mapped_pass) goto out;
|
||||
} else if (try_mapped_pass || use_mapped_pass) {
|
||||
char dcepass[MAP_PASSLEN+1];
|
||||
uid_t saved_uid;
|
||||
int got_mapped_pass;
|
||||
|
||||
saved_uid = geteuid();
|
||||
|
||||
if (saved_uid != pw_uid && getuid() == 0 &&
|
||||
seteuid(pw_uid) < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"xfn_get_mapped_passwd: seteuid: %m");
|
||||
/* continue since we might be able to get mapping */
|
||||
}
|
||||
|
||||
got_mapped_pass = xfn_get_mapped_password(
|
||||
debug ? XFN_MAP_DEBUG : 0, user, DCE_XFN_PASS_ATTR,
|
||||
firstpass, dcepass, sizeof (dcepass));
|
||||
|
||||
if (geteuid() != saved_uid && seteuid(saved_uid) < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"xfn_get_mapped_passwd seteuid restore: %m");
|
||||
/* XXX: what should we do here? */
|
||||
}
|
||||
|
||||
if (got_mapped_pass) {
|
||||
|
||||
result =
|
||||
attempt_dce_login(pamh, dsd, &st, user, dcepass);
|
||||
|
||||
memset(dcepass, 0, MAP_PASSLEN);
|
||||
|
||||
if (result == PAM_SUCCESS ||
|
||||
st == sec_login_s_acct_invalid) goto out;
|
||||
}
|
||||
if (use_mapped_pass) goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (firstpass == NULL) {
|
||||
if (use_first_pass) goto out;
|
||||
} else if (use_first_pass || try_first_pass) {
|
||||
|
||||
result = attempt_dce_login(pamh, dsd, &st,
|
||||
user, firstpass);
|
||||
|
||||
if (result == PAM_SUCCESS ||
|
||||
st == sec_login_s_acct_invalid ||
|
||||
use_first_pass) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the password from the user
|
||||
*/
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "DCE pam_sm_auth prompting for password");
|
||||
|
||||
if (firstpass == NULL &&
|
||||
!(try_first_pass||try_mapped_pass||invalid_user))
|
||||
(void) sprintf(messages[0], (const char *) PAM_MSG(pamh, 10,
|
||||
"Password: "));
|
||||
else
|
||||
(void) sprintf(messages[0], (const char *) PAM_MSG(pamh, 11,
|
||||
"DCE Password: "));
|
||||
|
||||
num_msg = 1;
|
||||
|
||||
err = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK,
|
||||
DCE_PASSWD_LENGTH,messages[0], &password);
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "DCE __pam_get_authtok = %d", err);
|
||||
|
||||
if (err != PAM_SUCCESS) {
|
||||
result = err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (password == NULL) {
|
||||
/* Need a password to proceed */
|
||||
result = PAM_AUTH_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (firstpass == NULL) {
|
||||
/* this is the first password, stash it away */
|
||||
pam_set_item(pamh, PAM_AUTHTOK, password);
|
||||
}
|
||||
|
||||
/* one last ditch attempt to login to DCE */
|
||||
|
||||
if (invalid_user || ignore)
|
||||
goto out;
|
||||
|
||||
result = attempt_dce_login(pamh, dsd, &st, user, password);
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
/* we had to prompt for DCE password, so attempt to */
|
||||
/* update mapping iff we got a good DCE password */
|
||||
|
||||
if (try_mapped_pass && result == PAM_SUCCESS && firstpass) {
|
||||
uid_t saved_uid;
|
||||
|
||||
saved_uid = geteuid();
|
||||
|
||||
if (saved_uid != pw_uid && seteuid(pw_uid) < 0) {
|
||||
syslog(LOG_ERR, "xfn_get_mapped_passwd: seteuid: %m");
|
||||
goto out;
|
||||
}
|
||||
|
||||
xfn_update_mapped_password(debug ? XFN_MAP_DEBUG : 0,
|
||||
user, DCE_XFN_PASS_ATTR, firstpass, password);
|
||||
|
||||
if (geteuid() != saved_uid && seteuid(saved_uid) < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"xfn_get_mapped_passwd seteuid restore: %m");
|
||||
/* XXX: what should we do here? */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
|
||||
if (ignore) {
|
||||
result = PAM_IGNORE;
|
||||
}
|
||||
|
||||
if (password != NULL)
|
||||
memset(password, 0, strlen(password));
|
||||
|
||||
if (invalid_user)
|
||||
result = PAM_USER_UNKNOWN;
|
||||
|
||||
if (dsd)
|
||||
dsd->auth_status = result;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
attempt_dce_login(
|
||||
void *pamh,
|
||||
dce_module_data_t *dsd,
|
||||
error_status_t *st,
|
||||
char *user,
|
||||
char *dce_pass)
|
||||
{
|
||||
sec_passwd_rec_t passwd_rec;
|
||||
boolean32 login_valid = 0;
|
||||
error_status_t set_st;
|
||||
|
||||
/* have to strdup password because the call clears it */
|
||||
passwd_rec.key.tagged_union.plain = (idl_char *) strdup(dce_pass);
|
||||
if (passwd_rec.key.tagged_union.plain == NULL) {
|
||||
return (PAM_BUF_ERR);
|
||||
}
|
||||
passwd_rec.key.key_type = sec_passwd_plain;
|
||||
passwd_rec.pepper = NULL;
|
||||
passwd_rec.version_number = sec_passwd_c_version_none;
|
||||
|
||||
login_valid = sec_login_valid_and_cert_ident(dsd->login_context,
|
||||
&passwd_rec, &dsd->reset_passwd, &dsd->auth_src, st);
|
||||
|
||||
if (dsd->debug) {
|
||||
dce_error_string_t text;
|
||||
|
||||
syslog(LOG_DEBUG, "sec_login_valid_and_cert_ident: %s",
|
||||
get_dce_error_message(*st, text));
|
||||
}
|
||||
|
||||
if (*st == sec_login_s_acct_invalid && dsd->warn) {
|
||||
char messages[1][PAM_MAX_MSG_SIZE];
|
||||
|
||||
sprintf(messages[0],
|
||||
PAM_MSG(pamh, 12, "Error: Your DCE Account has expired.\n"));
|
||||
__pam_display_msg(pamh, PAM_ERROR_MSG, 1, messages, NULL);
|
||||
}
|
||||
|
||||
/* the call to sec_login_valid_and_cert_ident already zeros */
|
||||
/* out the password, so we just free it */
|
||||
|
||||
free(passwd_rec.key.tagged_union.plain);
|
||||
|
||||
return (login_valid ? PAM_SUCCESS : PAM_AUTH_ERR);
|
||||
}
|
||||
|
||||
void
|
||||
dce_cleanup(
|
||||
pam_handle_t *pamh,
|
||||
void *data,
|
||||
int pam_status)
|
||||
{
|
||||
error_status_t st;
|
||||
dce_module_data_t *dsd = (dce_module_data_t *) data;
|
||||
int status;
|
||||
|
||||
if (dsd->debug) {
|
||||
syslog(LOG_DEBUG, "DCE dce_cleanup pam_sm_auth_status(%d)",
|
||||
dsd->auth_status);
|
||||
}
|
||||
|
||||
if (!dsd->login_context != sec_login_default_handle) {
|
||||
free(dsd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if pam_end as PAM_SUCCESS, clean up based on value in */
|
||||
/* auth_status, otherwise just purge the context */
|
||||
|
||||
if (pam_status == PAM_SUCCESS) {
|
||||
pam_sec_login_free_context(dsd->auth_status,
|
||||
&dsd->login_context, &st);
|
||||
} else {
|
||||
sec_login_purge_context(&dsd->login_context, &st);
|
||||
if (dsd->debug) {
|
||||
dce_error_string_t text;
|
||||
syslog(LOG_DEBUG, "sec_login_purge_context: %s",
|
||||
get_dce_error_message(st, text));
|
||||
}
|
||||
}
|
||||
|
||||
free(dsd);
|
||||
}
|
||||
475
cde/lib/pam/pam_modules/dce/dce_password.c
Normal file
475
cde/lib/pam/pam_modules/dce/dce_password.c
Normal file
@@ -0,0 +1,475 @@
|
||||
/* $XConsortium: dce_password.c /main/5 1996/05/09 04:26:43 drk $ */
|
||||
/*
|
||||
* Copyright (c) 1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)dce_password.c 1.22 96/02/14 SMI"
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <dce/acct.h>
|
||||
#include <dce/uuid.h>
|
||||
#include <dce/binding.h>
|
||||
#include <dce/sec_login.h>
|
||||
#include <dce/dce_error.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "pam_impl.h"
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
#include "xfn_mapping.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
dce_changepw(
|
||||
char *account_name,
|
||||
char *old_pass,
|
||||
char *new_pass);
|
||||
|
||||
static char *
|
||||
get_passwd(
|
||||
pam_handle_t *pamh,
|
||||
char *prompt);
|
||||
|
||||
/*
|
||||
* XXX: This module is NOT finished!
|
||||
*
|
||||
*/
|
||||
int
|
||||
pam_sm_chauthtok(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
char *user;
|
||||
int err, result = PAM_AUTH_ERR;
|
||||
char *newpass = NULL, *vnewpass = NULL;
|
||||
char *oldpass = NULL;
|
||||
int try_first_pass = 0;
|
||||
int use_first_pass = 0;
|
||||
char *firstpass = NULL;
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
int try_mapped_pass = 0;
|
||||
int use_mapped_pass = 0;
|
||||
uid_t saved_uid;
|
||||
#endif
|
||||
int i;
|
||||
int debug = 0;
|
||||
uid_t pw_uid;
|
||||
dce_module_data_t *dsd = NULL;
|
||||
error_status_t status;
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "DCE Authentication\n");
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "try_first_pass") == 0)
|
||||
try_first_pass = 1;
|
||||
else if (strcmp(argv[i], "use_first_pass") == 0)
|
||||
use_first_pass = 1;
|
||||
#ifdef XFN_MAPPING
|
||||
else if (strcmp(argv[i], "try_mapped_pass") == 0)
|
||||
try_mapped_pass = 1;
|
||||
else if (strcmp(argv[i], "use_mapped_pass") == 0)
|
||||
use_mapped_pass = 1;
|
||||
#endif
|
||||
else
|
||||
syslog(LOG_DEBUG, "illegal scheme option %s", argv[i]);
|
||||
}
|
||||
|
||||
|
||||
if (flags & PAM_PRELIM_CHECK) {
|
||||
|
||||
/* try and bind to registry master of local cell */
|
||||
|
||||
sec_rgy_handle_t rh = sec_rgy_default_handle;
|
||||
|
||||
sec_rgy_site_open_update(NULL, &rh, &status);
|
||||
if (status == error_status_ok) {
|
||||
sec_rgy_site_close(rh, &status);
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
|
||||
/* make sure PAM framework is telling us to update passwords */
|
||||
if (!(flags & PAM_UPDATE_AUTHTOK)) {
|
||||
syslog(LOG_ERR, "dce pam_sm_chauthtok: bad flags: %d", flags);
|
||||
return (PAM_SYSTEM_ERR);
|
||||
}
|
||||
|
||||
|
||||
if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) {
|
||||
if (pam_get_data(pamh, DCE_DATA, (void **)&dsd)
|
||||
== PAM_SUCCESS) {
|
||||
if (!dsd->passwd_expired)
|
||||
return (PAM_IGNORE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = pam_get_item(pamh, PAM_USER, (void **) &user)) < 0)
|
||||
return (err);
|
||||
|
||||
/* Don't bother to handle root in DCE */
|
||||
|
||||
if (strcmp(user, "root") == 0)
|
||||
return (PAM_IGNORE);
|
||||
|
||||
#ifdef XFN_MAPPING
|
||||
if (use_mapped_pass || try_mapped_pass) {
|
||||
int got_mapped = 0, updated_mapped = 0;
|
||||
char dcepass[MAP_PASSLEN+1];
|
||||
|
||||
if ((err = pam_get_item(pamh, PAM_AUTHTOK,
|
||||
(void **) &newpass)) < 0)
|
||||
return (err);
|
||||
if ((err = pam_get_item(pamh, PAM_OLDAUTHTOK,
|
||||
(void **) &oldpass)) < 0)
|
||||
return (err);
|
||||
|
||||
if (!get_pw_uid(user, &pw_uid)) {
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
|
||||
/* XXX: need to seteuid */
|
||||
|
||||
saved_uid = geteuid();
|
||||
|
||||
if (saved_uid != pw_uid && getuid() == 0 &&
|
||||
seteuid(pw_uid) < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"xfn_get_mapped_passwd: seteuid: %m");
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
|
||||
got_mapped = xfn_get_mapped_password(0, user,
|
||||
DCE_XFN_PASS_ATTR, oldpass, dcepass, sizeof (dcepass));
|
||||
|
||||
if (got_mapped) {
|
||||
|
||||
updated_mapped = xfn_update_mapped_password(
|
||||
0, user, DCE_XFN_PASS_ATTR, newpass,
|
||||
dcepass);
|
||||
|
||||
memset(dcepass, 0, sizeof (dcepass));
|
||||
|
||||
} else {
|
||||
/* probably should prompt for DCE password */
|
||||
/* and attempt to update it */
|
||||
}
|
||||
|
||||
if (geteuid() != saved_uid && seteuid(saved_uid) < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"xfn_get_mapped_passwd seteuid restore: %m");
|
||||
/* XXX: what should we do here? */
|
||||
}
|
||||
|
||||
if (use_mapped_pass) {
|
||||
if (updated_mapped)
|
||||
return (PAM_SUCCESS);
|
||||
else
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
#endif /* XFN_MAPPING */
|
||||
|
||||
if (try_first_pass || use_first_pass) {
|
||||
|
||||
if ((err = pam_get_item(pamh, PAM_AUTHTOK,
|
||||
(void **) &newpass)) < 0)
|
||||
return (err);
|
||||
if ((err = pam_get_item(pamh, PAM_OLDAUTHTOK,
|
||||
(void **) &oldpass)) < 0)
|
||||
return (err);
|
||||
|
||||
result = dce_changepw(user, oldpass, newpass);
|
||||
|
||||
if (result == PAM_SUCCESS) {
|
||||
/* might need to update PAM_OLDAUTHTOK and PAM_NEWAUTHTOK */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* assume we need to prompt for old DCE password? */
|
||||
|
||||
oldpass = get_passwd(pamh, PAM_MSG(pamh, 20,
|
||||
"Old DCE password: "));
|
||||
|
||||
if (oldpass == NULL || oldpass[0] == '\0') {
|
||||
/* Need a password to proceed */
|
||||
result = PAM_AUTHTOK_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = dce_changepw(user, oldpass, newpass);
|
||||
|
||||
if (result == PAM_SUCCESS) {
|
||||
/* might need to update PAM_OLDAUTHTOK and PAM_NEWAUTHTOK */
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* prompt for both old and new passwords */
|
||||
|
||||
if (firstpass == NULL && !(try_first_pass||try_mapped_pass))
|
||||
oldpass = get_passwd(pamh, PAM_MSG(pamh, 20,
|
||||
"Old DCE password: "));
|
||||
else
|
||||
oldpass = get_passwd(pamh, PAM_MSG(pamh, 20,
|
||||
"Old DCE password: "));
|
||||
|
||||
if (oldpass == NULL || oldpass[0] == '\0') {
|
||||
/* Need a password to proceed */
|
||||
result = PAM_AUTHTOK_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (firstpass == NULL && !(try_first_pass||try_mapped_pass))
|
||||
newpass = get_passwd(pamh, PAM_MSG(pamh, 21,
|
||||
"New DCE password: "));
|
||||
else
|
||||
newpass = get_passwd(pamh, PAM_MSG(pamh, 21,
|
||||
"New DCE password: "));
|
||||
|
||||
if (newpass == NULL || newpass[0] == '\0') {
|
||||
/* Need a password to proceed */
|
||||
result = PAM_AUTHTOK_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (firstpass == NULL && !(try_first_pass||try_mapped_pass))
|
||||
vnewpass = get_passwd(pamh,
|
||||
PAM_MSG(pamh, 22,
|
||||
"Re-enter new DCE password: "));
|
||||
else
|
||||
vnewpass = get_passwd(pamh,
|
||||
PAM_MSG(pamh, 22,
|
||||
"Re-enter new DCE password: "));
|
||||
|
||||
if (vnewpass == NULL || vnewpass[0] == '\0') {
|
||||
/* Need a password to proceed */
|
||||
result = PAM_AUTHTOK_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(newpass, vnewpass)) {
|
||||
result = PAM_AUTHTOK_ERR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = dce_changepw(user, oldpass, newpass);
|
||||
|
||||
if (result == PAM_SUCCESS) {
|
||||
/* might need to update PAM_OLDAUTHTOK and PAM_NEWAUTHTOK) */
|
||||
}
|
||||
out:
|
||||
|
||||
if (oldpass) {
|
||||
memset(oldpass, 0, strlen(oldpass));
|
||||
free(oldpass);
|
||||
}
|
||||
|
||||
if (newpass) {
|
||||
memset(newpass, 0, strlen(newpass));
|
||||
free(newpass);
|
||||
}
|
||||
|
||||
|
||||
if (vnewpass) {
|
||||
memset(vnewpass, 0, strlen(vnewpass));
|
||||
free(vnewpass);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
dce_changepw(
|
||||
char *account_name,
|
||||
char *old_pass,
|
||||
char *new_pass)
|
||||
{
|
||||
error_status_t status;
|
||||
sec_rgy_handle_t rgy_handle = sec_rgy_default_handle;
|
||||
sec_rgy_login_name_t name_key;
|
||||
sec_rgy_cursor_t account_cursor;
|
||||
sec_rgy_login_name_t name_result;
|
||||
sec_rgy_sid_t id_sid;
|
||||
sec_rgy_unix_sid_t unix_sid;
|
||||
sec_rgy_acct_key_t key_parts;
|
||||
sec_rgy_acct_user_t user_part;
|
||||
sec_rgy_acct_admin_t admin_part;
|
||||
sec_passwd_rec_t new_key, caller_key;
|
||||
sec_passwd_version_t new_key_version;
|
||||
sec_login_handle_t login_context = sec_login_default_handle;
|
||||
sec_passwd_rec_t passwd_rec;
|
||||
boolean32 reset_pass = 0, login_valid = 0;
|
||||
sec_login_auth_src_t auth_src;
|
||||
char *env;
|
||||
static char *krb5 = "KRB5CCNAME";
|
||||
char *krb5_value = NULL;
|
||||
|
||||
/* stash away the value of KRB5CCNAME, if there is one set */
|
||||
env = getenv(krb5);
|
||||
if (env) {
|
||||
krb5_value = malloc(strlen(krb5)+1+strlen(env)+1);
|
||||
if (krb5_value)
|
||||
sprintf(krb5_value, "%s=%s", krb5, env);
|
||||
else {
|
||||
status = sec_login_s_no_current_context;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* first we a get a login context. A future version should */
|
||||
/* check and see if there is a current context with the */
|
||||
/* same name as the user we are setting */
|
||||
|
||||
if (!sec_login_setup_identity((unsigned_char_p_t) account_name,
|
||||
sec_login_no_flags, &login_context, &status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* have to strdup password because the call clears it */
|
||||
passwd_rec.key.tagged_union.plain =
|
||||
(idl_char *) strdup(old_pass);
|
||||
if (passwd_rec.key.tagged_union.plain == NULL) {
|
||||
status = sec_login_s_no_current_context;
|
||||
goto out;
|
||||
}
|
||||
|
||||
passwd_rec.key.key_type = sec_passwd_plain;
|
||||
passwd_rec.pepper = NULL;
|
||||
passwd_rec.version_number = sec_passwd_c_version_none;
|
||||
|
||||
login_valid = sec_login_validate_identity(login_context,
|
||||
&passwd_rec, &reset_pass, &auth_src, &status);
|
||||
|
||||
free(passwd_rec.key.tagged_union.plain); /* already memset */
|
||||
|
||||
if (!login_valid)
|
||||
goto out;
|
||||
|
||||
sec_login_set_context(login_context, &status);
|
||||
|
||||
if (status != error_status_ok)
|
||||
goto out;
|
||||
|
||||
/* we now have a context with the same account as the one */
|
||||
/* we are trying to change the password on. Lets talk to the */
|
||||
/* registry... */
|
||||
|
||||
sec_rgy_site_open(NULL, &rgy_handle, &status);
|
||||
|
||||
if (status != error_status_ok) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
caller_key.key.key_type = sec_passwd_plain;
|
||||
caller_key.pepper = NULL;
|
||||
caller_key.version_number = sec_passwd_c_version_none;
|
||||
caller_key.key.tagged_union.plain = (idl_char *) old_pass;
|
||||
|
||||
sec_rgy_cursor_reset(&account_cursor);
|
||||
|
||||
strcpy((char *)name_key.pname, account_name);
|
||||
name_key.gname[0] = '\0';
|
||||
name_key.oname[0] = '\0';
|
||||
|
||||
/* need to do this in order to get the org and group for the */
|
||||
/* account. All we want is name_result... */
|
||||
|
||||
sec_rgy_acct_lookup(
|
||||
rgy_handle,
|
||||
&name_key,
|
||||
&account_cursor,
|
||||
&name_result,
|
||||
&id_sid,
|
||||
&unix_sid,
|
||||
&key_parts,
|
||||
&user_part,
|
||||
&admin_part,
|
||||
&status);
|
||||
|
||||
if (status != error_status_ok)
|
||||
goto out;
|
||||
|
||||
caller_key.key.key_type = sec_passwd_plain;
|
||||
caller_key.pepper = NULL;
|
||||
caller_key.version_number = sec_passwd_c_version_none;
|
||||
caller_key.key.tagged_union.plain = (idl_char *) old_pass;
|
||||
|
||||
new_key.key.key_type = sec_passwd_plain;
|
||||
new_key.pepper = NULL;
|
||||
new_key.version_number = sec_passwd_c_version_none;
|
||||
new_key.key.tagged_union.plain = (idl_char *) new_pass;
|
||||
|
||||
/* rock and roll. lets try to update the password... */
|
||||
|
||||
sec_rgy_acct_passwd(
|
||||
rgy_handle,
|
||||
&name_result,
|
||||
&caller_key,
|
||||
&new_key,
|
||||
sec_passwd_des,
|
||||
&new_key_version,
|
||||
&status);
|
||||
|
||||
out:
|
||||
/* restore the old KRB5CCNAME value */
|
||||
if (krb5_value) {
|
||||
putenv(krb5_value);
|
||||
}
|
||||
|
||||
if (rgy_handle != sec_rgy_default_handle) {
|
||||
error_status_t st; /* don't trash status */
|
||||
|
||||
sec_rgy_site_close(rgy_handle, &st);
|
||||
}
|
||||
|
||||
if (login_context != sec_login_default_handle) {
|
||||
error_status_t st; /* don't trash status */
|
||||
|
||||
sec_login_purge_context(&login_context, &st);
|
||||
}
|
||||
|
||||
if (status == error_status_ok) {
|
||||
return (PAM_SUCCESS);
|
||||
} else {
|
||||
return (PAM_AUTHTOK_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
get_passwd(
|
||||
pam_handle_t *pamh,
|
||||
char *prompt)
|
||||
{
|
||||
int err;
|
||||
char *p;
|
||||
|
||||
err = __pam_get_authtok(pamh, PAM_PROMPT, 0, 256, prompt, &p);
|
||||
|
||||
if (err != PAM_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
49
cde/lib/pam/pam_modules/dce/dce_session.c
Normal file
49
cde/lib/pam/pam_modules/dce/dce_session.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* $XConsortium: dce_session.c /main/4 1996/05/09 04:27:00 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)dce_session.c 1.3 96/01/10 SMI"
|
||||
|
||||
#include <libintl.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <dce/sec_login.h>
|
||||
#include <dce/dce_error.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include "pam_impl.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
* pam_sm_open_session
|
||||
*/
|
||||
int
|
||||
pam_sm_open_session(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* pam_sm_close_session
|
||||
*/
|
||||
int
|
||||
pam_sm_close_session(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
125
cde/lib/pam/pam_modules/dce/dce_setcred.c
Normal file
125
cde/lib/pam/pam_modules/dce/dce_setcred.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* $XConsortium: dce_setcred.c /main/5 1996/05/09 04:27:17 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)dce_setcred.c 1.21 96/01/11 SMI"
|
||||
|
||||
#include <libintl.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <dce/sec_login.h>
|
||||
#include <dce/dce_error.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include "pam_impl.h"
|
||||
#include "utils.h"
|
||||
|
||||
static void
|
||||
do_cred_warn(void *pamh)
|
||||
{
|
||||
char messages[1][PAM_MAX_MSG_SIZE];
|
||||
|
||||
sprintf(messages[0],
|
||||
PAM_MSG(pamh, 30, "warning: Unable to obtain DCE credentials.\n"));
|
||||
|
||||
(void) __pam_display_msg(pamh, PAM_ERROR_MSG, 1, messages, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* pam_sm_setcred
|
||||
*/
|
||||
int
|
||||
pam_sm_setcred(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
int debug = 0;
|
||||
int warn = 1;
|
||||
int i;
|
||||
dce_module_data_t *dsd;
|
||||
error_status_t st;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
if (strcmp(argv[i], "nowarn") == 0)
|
||||
warn = 0;
|
||||
}
|
||||
|
||||
if (flags & PAM_SILENT) warn = 0;
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "DCE pam_setcred");
|
||||
|
||||
if (pam_get_data(pamh, DCE_DATA, (void**)&dsd) != PAM_SUCCESS ||
|
||||
dsd == NULL) {
|
||||
if (flags & PAM_DELETE_CRED) {
|
||||
sec_login_handle_t context;
|
||||
|
||||
/* attempt to get current context and purge */
|
||||
sec_login_get_current_context(&context, &st);
|
||||
if (st == error_status_ok) {
|
||||
sec_login_purge_context(&context, &st);
|
||||
}
|
||||
return (st == error_status_ok ? PAM_SUCCESS :
|
||||
PAM_CRED_UNAVAIL);
|
||||
}
|
||||
|
||||
if (warn) do_cred_warn(pamh);
|
||||
return (PAM_IGNORE); /* since pam_auth was never called */
|
||||
}
|
||||
|
||||
if (dsd->auth_status != PAM_SUCCESS)
|
||||
return (dsd->auth_status);
|
||||
|
||||
if (flags & PAM_DELETE_CRED) {
|
||||
(void) sec_login_purge_context(dsd->login_context, &st);
|
||||
|
||||
if (debug) {
|
||||
dce_error_string_t text;
|
||||
|
||||
syslog(LOG_DEBUG,
|
||||
"PAM: DCE sec_login_purge_context: %s",
|
||||
get_dce_error_message(st, text));
|
||||
}
|
||||
|
||||
} else {
|
||||
if (dsd->auth_src == sec_login_auth_src_local) {
|
||||
/* we can't set_context on locally authenticated */
|
||||
/* contexts */
|
||||
st = sec_login_s_auth_local;
|
||||
} else {
|
||||
(void) sec_login_set_context(dsd->login_context, &st);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
dce_error_string_t text;
|
||||
|
||||
syslog(LOG_DEBUG, "PAM: DCE sec_login_set_context: %s",
|
||||
get_dce_error_message(st, text));
|
||||
}
|
||||
}
|
||||
|
||||
/* might want an option to return success even if set_context failed */
|
||||
|
||||
if (st == error_status_ok) {
|
||||
return (PAM_SUCCESS);
|
||||
} else {
|
||||
if (warn) do_cred_warn(pamh);
|
||||
|
||||
if (debug) syslog(LOG_DEBUG,
|
||||
"Can't set user login context");
|
||||
return (PAM_CRED_ERR);
|
||||
}
|
||||
}
|
||||
22
cde/lib/pam/pam_modules/dce/libpam_cde.elist
Normal file
22
cde/lib/pam/pam_modules/dce/libpam_cde.elist
Normal file
@@ -0,0 +1,22 @@
|
||||
/****************************************************************************
|
||||
* Export list for libpam_dce.
|
||||
* This list *must* be updated whenever a change is made to the libpam_dce
|
||||
* API.
|
||||
*
|
||||
* The syntax for the symbol declarations in this list is as follows:
|
||||
* public sym => Public C symbol, i.e., publicised API
|
||||
* private sym => Private C symbol, i.e., unpublicised API
|
||||
* internal sym => Internal C symbol, i.e., not part of API
|
||||
* publicC++ sym => Public C++ symbol, i.e., publicised API
|
||||
* privateC++ sym => Private C++ symbol, i.e., unpublicised API
|
||||
* internalC++ sym => Internal C++ symbol, i.e., not part of API
|
||||
*
|
||||
* $TOG: libpam_cde.elist /main/1 1999/09/08 15:58:14 mgreess $
|
||||
*****************************************************************************/
|
||||
|
||||
public pam_sm_authenticate
|
||||
public pam_sm_setcred
|
||||
public pam_sm_acct_mgmt
|
||||
public pam_sm_open_session
|
||||
public pam_sm_close_session
|
||||
public pam_sm_chauthtok
|
||||
71
cde/lib/pam/pam_modules/dce/pam_dce.msg
Normal file
71
cde/lib/pam/pam_modules/dce/pam_dce.msg
Normal file
@@ -0,0 +1,71 @@
|
||||
$ $XConsortium: pam_dce.msg /main/2 1996/07/24 19:04:00 drk $
|
||||
$ *************************************<+>*************************************
|
||||
$ *****************************************************************************
|
||||
$ **
|
||||
$ ** File: pam_dce.msg
|
||||
$ **
|
||||
$ ** Project: pam_dce
|
||||
$ **
|
||||
$ ** Description:
|
||||
$ ** -----------
|
||||
$ ** This file is the source for the message catalog for pam_unix module.
|
||||
$ **
|
||||
$ **
|
||||
$ *****************************************************************************
|
||||
$ **
|
||||
$ ** (c) Copyright 1996 Sun Microsystems, Inc.
|
||||
$ ** All Rights reserved
|
||||
$ **
|
||||
$ *****************************************************************************
|
||||
$ *************************************<+>*************************************
|
||||
|
||||
$ *****************************************************************************
|
||||
$
|
||||
$ ***** NOTE FOR MESSAGE CATALOG TRANSLATORS *****
|
||||
$
|
||||
$ There may be three types of messages in this file:
|
||||
$
|
||||
$ 1. Messages that appear in dialogs or are displayed to the user.
|
||||
$
|
||||
$ These messages are the default and they should ALL BE LOCALIZED.
|
||||
$ Note that these messages do NOT have any identification (see the
|
||||
$ comments for type 2 and 3 below).
|
||||
$
|
||||
$ 2. Messages that only appear in the error log file.
|
||||
$
|
||||
$ The localization of these messages is OPTIONAL. These messages are
|
||||
$ identified by the following:
|
||||
$
|
||||
$ MESSAGES xx-yy IN SET zz WILL ONLY APPEAR IN THE DT ERRORLOG FILE
|
||||
$
|
||||
$ 3. Messages that should not be localized.
|
||||
$
|
||||
$ These messages are identified by the following:
|
||||
$
|
||||
$ DO NOT TRANSLATE or CHANGE or LOCALIZE MESSAGES xx-yy from set zz
|
||||
$
|
||||
$ ***** END (NOTE FOR MESSAGE CATALOG TRANSLATORS) *****
|
||||
$
|
||||
$ ******************************************************************************
|
||||
|
||||
$set 1
|
||||
|
||||
$ dce_acct_mgmt.c
|
||||
1 Warning: Your DCE %s has expired.
|
||||
2 Warning: Your DCE %s will expire within %d hour%s.
|
||||
3 Warning: Your DCE %s will expire in 2 days.\n
|
||||
4 Warning: Your DCE passwd has expired.
|
||||
|
||||
$ dce_authenticate.c
|
||||
10 Password:
|
||||
11 DCE Password:
|
||||
12 Error: Your DCE Account has expired.\n
|
||||
|
||||
$ dce_password.c
|
||||
20 Old DCE password:
|
||||
21 New DCE password:
|
||||
22 Re-enter new DCE password:
|
||||
|
||||
$ dce_setcred.c
|
||||
30 warning: Unable to obtain DCE credentials.\n
|
||||
|
||||
96
cde/lib/pam/pam_modules/dce/utils.c
Normal file
96
cde/lib/pam/pam_modules/dce/utils.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* $XConsortium: utils.c /main/4 1996/05/09 04:27:30 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)utils.c 1.13 95/09/19 SMI"
|
||||
|
||||
#include <dce/sec_login.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/* ******************************************************************** */
|
||||
/* */
|
||||
/* Utilities Functions */
|
||||
/* */
|
||||
/* ******************************************************************** */
|
||||
|
||||
|
||||
/* return a string given an error status */
|
||||
|
||||
unsigned char *
|
||||
get_dce_error_message(
|
||||
error_status_t status,
|
||||
unsigned char *buffer
|
||||
)
|
||||
{
|
||||
int s;
|
||||
|
||||
dce_error_inq_text(status, buffer, &s);
|
||||
|
||||
if (s)
|
||||
sprintf((char *)buffer, "DCE error %u", status);
|
||||
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
/* release login_context resources. if we are returning PAM_SUCCESS */
|
||||
/* we also have to save KRB5CCNAME and set it after calling release */
|
||||
/* because s_l_release_c unset's it even though we still need it */
|
||||
|
||||
void
|
||||
pam_sec_login_free_context(
|
||||
int pam_status,
|
||||
sec_login_handle_t *login_context,
|
||||
error_status_t *st)
|
||||
{
|
||||
if (pam_status == PAM_SUCCESS) {
|
||||
static char *krb5 = "KRB5CCNAME";
|
||||
char *krb5_value = NULL;
|
||||
char *env = getenv(krb5);
|
||||
|
||||
if (env) {
|
||||
/* we MUST malloc this for the putenv to work! */
|
||||
krb5_value = malloc(strlen(krb5)+1+strlen(env)+1);
|
||||
if (krb5_value)
|
||||
sprintf(krb5_value, "%s=%s", krb5, env);
|
||||
}
|
||||
|
||||
sec_login_release_context(login_context, st);
|
||||
|
||||
if (krb5_value)
|
||||
putenv(krb5_value);
|
||||
|
||||
} else { /* login failed. purge this context */
|
||||
|
||||
sec_login_purge_context(login_context, st);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_pw_uid():
|
||||
* To get the uid from the passwd entry for specified user
|
||||
* It returns 0 if the user can't be found, otherwise returns 1.
|
||||
*/
|
||||
|
||||
int
|
||||
get_pw_uid(char *user, uid_t *uid)
|
||||
{
|
||||
struct passwd sp;
|
||||
char buffer[1024];
|
||||
|
||||
if (getpwnam_r(user, &sp, buffer, sizeof (buffer)) == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
*uid = sp.pw_uid;
|
||||
|
||||
return (1);
|
||||
}
|
||||
58
cde/lib/pam/pam_modules/dce/utils.h
Normal file
58
cde/lib/pam/pam_modules/dce/utils.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* $XConsortium: utils.h /main/5 1996/05/09 04:27:45 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
#ident "@(#)utils.h 1.17 96/01/10 SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <dce/sec_login.h>
|
||||
|
||||
#define DCE_DATA "SUNW-DCE-AUTH-DATA"
|
||||
|
||||
/*
|
||||
* PAM_MSG macro for return of internationalized text
|
||||
*/
|
||||
|
||||
#define PAM_MSG(pamh, number, string)\
|
||||
(char *) __pam_get_i18n_msg(pamh, "pam_dce", 1, number, string)
|
||||
|
||||
typedef struct {
|
||||
sec_login_handle_t login_context;
|
||||
int debug;
|
||||
int warn;
|
||||
int auth_status;
|
||||
boolean32 reset_passwd;
|
||||
boolean32 passwd_expired;
|
||||
sec_login_auth_src_t auth_src;
|
||||
} dce_module_data_t;
|
||||
|
||||
void
|
||||
pam_sec_login_free_context(
|
||||
int pam_status,
|
||||
sec_login_handle_t *login_context,
|
||||
error_status_t *st);
|
||||
|
||||
unsigned char *
|
||||
get_dce_error_message(
|
||||
error_status_t status,
|
||||
unsigned char *buffer
|
||||
);
|
||||
|
||||
int
|
||||
get_pw_uid(char *user, uid_t *uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DCE_UTILS_H */
|
||||
287
cde/lib/pam/pam_modules/dce/xfn_mapping.c
Normal file
287
cde/lib/pam/pam_modules/dce/xfn_mapping.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/* $XConsortium: xfn_mapping.c /main/4 1996/05/09 04:28:00 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ident "@(#)xfn_mapping.c 1.6 95/09/19 SMI"
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <xfn/xfn.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "xfn_mapping.h"
|
||||
|
||||
static char hexval(char);
|
||||
static int hex2bin(int, char *, char *);
|
||||
static int bin2hex(int, unsigned char *, char *);
|
||||
|
||||
/*
|
||||
* attempt to get mapped password from XFN
|
||||
*/
|
||||
|
||||
int
|
||||
xfn_get_mapped_password(
|
||||
int flags,
|
||||
char *user, /* xfn user */
|
||||
char *xfn_attr, /* xfn attribute that holds the target pass */
|
||||
char *key, /* key (password) encrypting target password */
|
||||
char *out, /* un-encrypted target password */
|
||||
int out_max) /* buffer size of out */
|
||||
{
|
||||
|
||||
FN_status_t *status = NULL;
|
||||
FN_composite_name_t *compname = NULL;
|
||||
FN_ctx_t *ctx = NULL;
|
||||
FN_string_t *str = NULL;
|
||||
FN_attribute_t *attr = NULL;
|
||||
const FN_attrvalue_t *attr_val = NULL;
|
||||
FN_identifier_t attr_id; /* attr identifier */
|
||||
FN_identifier_t attr_syn; /* attr syntax */
|
||||
char hexpass[MAP_HEXLEN+1];
|
||||
char pass[MAP_PASSLEN+1];
|
||||
char composed_user[128]; /* XXX 128? */
|
||||
int result = 0;
|
||||
void *pos;
|
||||
|
||||
pass[0] = '\0';
|
||||
|
||||
status = fn_status_create(); /* free status */
|
||||
if (status == NULL)
|
||||
goto out;
|
||||
|
||||
ctx = fn_ctx_handle_from_initial(status); /* free ctx */
|
||||
if (ctx == NULL)
|
||||
goto out;
|
||||
|
||||
attr_id.format = FN_ID_STRING;
|
||||
attr_id.length = strlen(xfn_attr);
|
||||
attr_id.contents = xfn_attr;
|
||||
|
||||
if (strlen(user) > (sizeof (composed_user)-6))
|
||||
goto out;
|
||||
|
||||
sprintf(composed_user, "user/%s", user);
|
||||
|
||||
str = fn_string_from_str(
|
||||
(unsigned char *)composed_user); /* free str */
|
||||
if (str == NULL)
|
||||
goto out;
|
||||
|
||||
compname = fn_composite_name_from_string(str); /* free compname */
|
||||
if (compname == NULL)
|
||||
goto out;
|
||||
|
||||
attr = fn_attr_get(ctx, compname, &attr_id, status); /* free attr */
|
||||
if (attr == NULL)
|
||||
goto out;
|
||||
|
||||
attr_val = fn_attribute_first(attr, &pos); /* don't have to free */
|
||||
if (attr_val == NULL)
|
||||
goto out;
|
||||
|
||||
if (attr_val->length != MAP_HEXLEN)
|
||||
goto out;
|
||||
|
||||
memcpy(hexpass, attr_val->contents, attr_val->length);
|
||||
|
||||
if (xdecrypt(hexpass, key) == 0)
|
||||
goto out;
|
||||
|
||||
hexpass[MAP_HEXLEN] = '\0';
|
||||
|
||||
hex2bin(MAP_PASSLEN, hexpass, pass); /* we have the password!! */
|
||||
memset(hexpass, 0, MAP_HEXLEN);
|
||||
|
||||
if (strlen(pass)+1 > out_max)
|
||||
goto out; /* sigh... */
|
||||
|
||||
strcpy(out, pass);
|
||||
memset(pass, 0, strlen(pass));
|
||||
|
||||
result = 1;
|
||||
|
||||
out:
|
||||
if (pass[0])
|
||||
memset(pass, 0, MAP_PASSLEN);
|
||||
if (status)
|
||||
fn_status_destroy(status);
|
||||
if (ctx)
|
||||
fn_ctx_handle_destroy(ctx);
|
||||
if (str)
|
||||
fn_string_destroy(str);
|
||||
if (compname)
|
||||
fn_composite_name_destroy(compname);
|
||||
if (attr)
|
||||
fn_attribute_destroy(attr);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* attempt to update mapped password from XFN
|
||||
*/
|
||||
|
||||
int
|
||||
xfn_update_mapped_password(
|
||||
int flags, /* debug, etc */
|
||||
char *user, /* xfn user */
|
||||
char *xfn_attr, /* xfn attribute that holds the target pass */
|
||||
char *key, /* key (password) encrypting target password */
|
||||
char *password) /* un-encrypted target password */
|
||||
{
|
||||
|
||||
FN_status_t *status = NULL;
|
||||
FN_composite_name_t *compname = NULL;
|
||||
FN_ctx_t *ctx = NULL;
|
||||
FN_ref_t *ref = NULL;
|
||||
FN_string_t *str = NULL;
|
||||
FN_attribute_t *attr = NULL;
|
||||
FN_identifier_t attr_id; /* attr identifier */
|
||||
FN_identifier_t attr_syn; /* attr syntax */
|
||||
FN_attrvalue_t attr_val;
|
||||
char hexpass[MAP_HEXLEN+1];
|
||||
char pass[MAP_PASSLEN+1];
|
||||
char composed_user[128]; /* XXX 128? */
|
||||
int result;
|
||||
|
||||
result = 0; /* guilty until proven innocent */
|
||||
hexpass[0] = '\0';
|
||||
|
||||
if (strlen(pass) > MAP_PASSLEN)
|
||||
goto out;
|
||||
|
||||
status = fn_status_create(); /* free status */
|
||||
if (status == NULL)
|
||||
goto out;
|
||||
|
||||
ctx = fn_ctx_handle_from_initial(status); /* free ctx */
|
||||
if (ctx == NULL)
|
||||
goto out;
|
||||
|
||||
attr_id.format = FN_ID_STRING;
|
||||
attr_id.length = strlen(xfn_attr);
|
||||
attr_id.contents = xfn_attr;
|
||||
attr_syn.format = FN_ID_STRING;
|
||||
#define PASSWD_ATTR_SYNTAX "fn_attr_syntax_ascii"
|
||||
attr_syn.length = sizeof (PASSWD_ATTR_SYNTAX)-1; /* sizeof has null */
|
||||
attr_syn.contents = PASSWD_ATTR_SYNTAX;
|
||||
|
||||
attr = fn_attribute_create(&attr_id, &attr_syn); /* free attr */
|
||||
|
||||
if (strlen(user) > (sizeof (composed_user)-6))
|
||||
goto out;
|
||||
|
||||
sprintf(composed_user, "user/%s", user);
|
||||
str = fn_string_from_str(
|
||||
(unsigned char *)composed_user); /* free str */
|
||||
|
||||
if (str == NULL)
|
||||
goto out;
|
||||
|
||||
compname = fn_composite_name_from_string(str); /* free compname */
|
||||
if (compname == NULL)
|
||||
goto out;
|
||||
|
||||
ref = fn_ctx_lookup(ctx, compname, status);
|
||||
if (ref == NULL)
|
||||
goto out;
|
||||
|
||||
strcpy(pass, password);
|
||||
bin2hex(MAP_PASSLEN, (unsigned char *)pass, hexpass);
|
||||
hexpass[MAP_HEXLEN] = '\0';
|
||||
|
||||
memset(pass, 0, sizeof (pass));
|
||||
|
||||
if (xencrypt(hexpass, key) == 0)
|
||||
goto out;
|
||||
|
||||
attr_val.length = strlen(hexpass);
|
||||
attr_val.contents = hexpass;
|
||||
|
||||
if (fn_attribute_add(attr, &attr_val, 1) == 0)
|
||||
goto out;
|
||||
|
||||
if (fn_attr_modify(ctx, compname, FN_ATTR_OP_ADD, attr, status) == 0)
|
||||
goto out;
|
||||
|
||||
result = 1;
|
||||
|
||||
out:
|
||||
if (hexpass[0])
|
||||
memset(hexpass, 0, MAP_HEXLEN);
|
||||
if (status)
|
||||
fn_status_destroy(status);
|
||||
if (ctx)
|
||||
fn_ctx_handle_destroy(ctx);
|
||||
if (str)
|
||||
fn_string_destroy(str);
|
||||
if (compname)
|
||||
fn_composite_name_destroy(compname);
|
||||
if (attr)
|
||||
fn_attribute_destroy(attr);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hex to binary conversion
|
||||
*/
|
||||
static
|
||||
hex2bin(int len, char *hexnum, char *binnum)
|
||||
{
|
||||
int i;
|
||||
char v1;
|
||||
char v2;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
v1 = hexval(hexnum[2 * i]);
|
||||
if (v1 == -1)
|
||||
return (0);
|
||||
v2 = hexval(hexnum[2 * i + 1]);
|
||||
if (v2 == -1)
|
||||
return (0);
|
||||
*binnum++ = (v1 << 4) + v2;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary to hex conversion
|
||||
*/
|
||||
static
|
||||
bin2hex(int len, unsigned char *binnum, char *hexnum)
|
||||
{
|
||||
int i;
|
||||
unsigned val;
|
||||
static char hex[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
};
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
val = binnum[i];
|
||||
hexnum[i*2] = hex[val >> 4];
|
||||
hexnum[i*2+1] = hex[val & 0xf];
|
||||
}
|
||||
hexnum[len*2] = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static char
|
||||
hexval(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') {
|
||||
return (c - '0');
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
return (c - 'a' + 10);
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
46
cde/lib/pam/pam_modules/dce/xfn_mapping.h
Normal file
46
cde/lib/pam/pam_modules/dce/xfn_mapping.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* $XConsortium: xfn_mapping.h /main/4 1996/05/09 04:28:15 drk $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _XFN_MAPPING_H
|
||||
#define _XFN_MAPPING_H
|
||||
|
||||
#ident "@(#)xfn_mapping.h 1.6 95/09/19 SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAP_PASSLEN 32 /* XXX max mapped passwd length */
|
||||
#define MAP_HEXLEN (2*MAP_PASSLEN) /* XXX max passwd length in hex */
|
||||
#define DCE_XFN_PASS_ATTR "onc_dce_passwd"
|
||||
|
||||
#define XFN_MAP_DEBUG 0x1 /* enable debugging */
|
||||
|
||||
int
|
||||
xfn_get_mapped_password(
|
||||
int flags, /* XFN_MAP_DEBUG, etc */
|
||||
char *user, /* xfn user */
|
||||
char *xfn_attr, /* xfn attribute that holds the target pass */
|
||||
char *key, /* key (password) encrypting target password */
|
||||
char *out, /* un-encrypted target password */
|
||||
int max_out_len /* buffer size of out */
|
||||
);
|
||||
|
||||
int
|
||||
xfn_update_mapped_password(
|
||||
int flags, /* XFN_MAP_DEBUG, etc */
|
||||
char *user, /* xfn user */
|
||||
char *xfn_attr, /* xfn attribute that holds the target pass */
|
||||
char *key, /* key (password) encrypting target password */
|
||||
char *password /* un-encrypted target password */
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user