Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View 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()

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}
}

View 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

View 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

View 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);
}

View 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 */

View 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);
}
}

View 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