ldap_attr.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ns_sldap.h"
#include <nss_dbdefs.h>
#include <nsswitch.h>
#include <pwd.h>
#include <shadow.h>
#include <syslog.h>
#include "passwdutil.h"
#include "utils.h"
void **buf);
char **auth_user, int *privileged);
/*
* ldap function pointer table, used by passwdutil_init to initialize
* the global Repository-OPerations table "rops"
*/
struct repops ldap_repops = {
NULL, /* checkhistory */
NULL, /* lock */
NULL /* unlock */
};
/*
*/
typedef struct {
char *passwd; /* encrypted password */
} ldapbuf_t;
/*
* The following define's are taken from
*/
/* passwd attributes filters */
#define _PWD_CN "cn"
#define _PWD_UID "uid"
#define _PWD_USERPASSWORD "userpassword"
#define _PWD_UIDNUMBER "uidnumber"
#define _PWD_GIDNUMBER "gidnumber"
#define _PWD_GECOS "gecos"
#define _PWD_DESCRIPTION "description"
#define _PWD_HOMEDIRECTORY "homedirectory"
#define _PWD_LOGINSHELL "loginshell"
/*
* int ldap_user_to_authenticate(user, rep, auth_user, privileged)
*
* We can't determine whether the user is "privileged" in the LDAP
* sense. The operation should be attempted and will succeed if
* the user had privileges.
*
* is attempting to change another user's password attributes.
*/
int
char **auth_user, int *privileged)
{
int res = PWU_SUCCESS;
return (PWU_NOT_FOUND);
return (PWU_NOT_FOUND);
/* changing out own, not privileged */
*privileged = 0;
} else {
char pwd_buf[1024];
*privileged = 1;
/*
* specific case for root
* we want 'user' to be authenticated.
*/
if (uid == 0) {
} else {
}
} else {
/* hmm. can't find name of current user...??? */
} else {
(int)uid);
}
}
}
return (res);
}
/*
* int ldap_getattr(name, item, rep)
*
* retrieve attributes specified in "item" for user "name".
*/
/*ARGSUSED*/
int
{
int res;
attrlist *w;
int need_shadow = 0; /* Need shadow info from LDAP server */
int need_normal = 0; /* Need non-shadow info from LDAP server */
/* We need the "shadow" map for the password only */
if (w->type == ATTR_PASSWD ||
w->type == ATTR_PASSWD_SERVER_POLICY)
need_shadow = 1;
else
need_normal = 1;
}
if (need_normal) {
if (res != PWU_SUCCESS)
goto out;
}
if (need_shadow) {
if (res != PWU_SUCCESS) {
goto out;
}
}
switch (w->type) {
case ATTR_NAME:
break;
case ATTR_COMMENT:
break;
case ATTR_GECOS:
break;
case ATTR_HOMEDIR:
break;
case ATTR_SHELL:
break;
case ATTR_PASSWD:
break;
case ATTR_AGE:
break;
case ATTR_REP_NAME:
break;
/* integer values */
case ATTR_UID:
break;
case ATTR_GID:
break;
case ATTR_LSTCHG:
break;
case ATTR_MIN:
break;
case ATTR_MAX:
break;
case ATTR_WARN:
break;
case ATTR_INACT:
break;
case ATTR_EXPIRE:
break;
case ATTR_FLAG:
break;
default:
break;
}
}
out:
if (pw)
if (spw)
return (res);
}
/*
* int ldap_getpwnam(name, items, rep, buf)
*
* There is no need to get the old values from the ldap
* server, as the update will update each item individually.
* Therefore, we only allocate a buffer that will be used by
* _update and _putpwnam to hold the attributes to update.
*
* Only when we're about to update a password, we need to retrieve
* the old password since it contains salt-information.
*/
/*ARGSUSED*/
int
void **buf)
{
attrlist *p;
int nr_items;
int need_pwd = 0;
int res;
nr_items++;
if (p->type == ATTR_PASSWD ||
p->type == ATTR_PASSWD_SERVER_POLICY)
need_pwd = 1;
}
return (PWU_NOMEM);
return (PWU_NOMEM);
if (need_pwd) {
if (res != PWU_SUCCESS)
return (res);
if (spw) {
return (PWU_NOMEM);
}
}
return (0);
}
/*
* new_attr(name, value)
*
* create a new LDAP attribute to be sent to the server
*/
{
return (NULL);
}
}
return (tmp);
}
/*
* ldap_update(items, rep, buf)
*
* create LDAP attributes in 'buf' for each attribute in 'items'.
*/
/*ARGSUSED*/
int
{
attrlist *p;
int idx = 0;
char *salt;
switch (p->type) {
case ATTR_PASSWD:
return (PWU_NOMEM);
else {
/* algorithm problem? */
"passwdutil: crypt_gensalt "
"%m");
return (PWU_UPDATE_FAILED);
}
}
return (PWU_NOMEM);
break;
/*
* For server policy, don't crypt the password,
* send the password as is to the server and
* let the LDAP server do its own password
* encryption
*/
return (PWU_NOMEM);
break;
case ATTR_COMMENT:
/* XX correct? */
break;
case ATTR_GECOS:
break;
case ATTR_HOMEDIR:
break;
case ATTR_SHELL:
break;
/* Unsupported items are below this line */
case ATTR_NAME:
case ATTR_UID:
case ATTR_GID:
case ATTR_AGE:
case ATTR_LSTCHG:
case ATTR_MIN:
case ATTR_MAX:
case ATTR_WARN:
case ATTR_INACT:
case ATTR_EXPIRE:
case ATTR_FLAG:
break;
default:
break;
}
return (PWU_NOMEM);
idx++;
}
return (PWU_SUCCESS);
}
/*
* ldap_to_pwu_code(error, pwd_status)
*
* translation from LDAP return values and PWU return values
*/
int
{
switch (error) {
case NS_LDAP_SUCCESS: return (PWU_SUCCESS);
case NS_LDAP_OP_FAILED: return (PWU_DENIED);
case NS_LDAP_NOTFOUND: return (PWU_NOT_FOUND);
case NS_LDAP_MEMORY: return (PWU_NOMEM);
case NS_LDAP_CONFIG: return (PWU_NOT_FOUND);
case NS_LDAP_INTERNAL:
switch (pwd_status) {
case NS_PASSWD_EXPIRED:
return (PWU_DENIED);
return (PWU_CHANGE_NOT_ALLOWED);
case NS_PASSWD_TOO_SHORT:
return (PWU_PWD_TOO_SHORT);
case NS_PASSWD_INVALID_SYNTAX:
return (PWU_PWD_INVALID);
case NS_PASSWD_IN_HISTORY:
return (PWU_PWD_IN_HISTORY);
case NS_PASSWD_WITHIN_MIN_AGE:
return (PWU_WITHIN_MIN_AGE);
default:
return (PWU_SYSTEM_ERROR);
}
default: return (PWU_SYSTEM_ERROR);
}
}
int
const char *pwd, int *pwd_status)
{
int result = NS_LDAP_OP_FAILED;
int ldaprc;
int authstried = 0;
return (PWU_NOMEM);
/* Fill in the user name and password */
goto out;
/* get host certificate path, if one is configured */
if (ldaprc != NS_LDAP_SUCCESS)
goto out;
/* Load the service specific authentication method */
&errorp);
if (ldaprc != NS_LDAP_SUCCESS)
goto out;
/*
* if authpp is null, there is no serviceAuthenticationMethod
* try default authenticationMethod
*/
&errorp);
if (ldaprc != NS_LDAP_SUCCESS)
goto out;
}
/*
* if authpp is still null, then can not authenticate, syslog
* error message and return error
*/
"passwdutil: no legal LDAP authentication method configured");
goto out;
}
/*
* Walk the array and try all authentication methods in order except
* for "none".
*/
continue;
authstried++;
(const ns_ldap_attr_t * const *)attrs,
if (ldaprc == NS_LDAP_SUCCESS) {
goto out;
}
/*
* other errors might need to be added to this list, for
* the current supported mechanisms this is sufficient
*/
if ((ldaprc == NS_LDAP_INTERNAL) &&
goto out;
}
/*
* If there is error related to password policy,
* return it to caller
*/
if ((ldaprc == NS_LDAP_INTERNAL) &&
goto out;
} else
/* we don't really care about the error, just clean it up */
if (errorp)
(void) __ns_ldap_freeError(&errorp);
}
if (authstried == 0) {
"passwdutil: no legal LDAP authentication method configured");
goto out;
}
result = PWU_DENIED;
out:
if (credp)
(void) __ns_ldap_freeCred(&credp);
if (authpp)
(void) __ns_ldap_freeParam((void ***)&authpp);
if (errorp)
(void) __ns_ldap_freeError(&errorp);
return (result);
}
/*
* ldap_putpwnam(name, oldpw, dummy, rep, buf)
*
* update the LDAP server with the attributes contained in 'buf'.
* The dummy parameter is a placeholder for NIS+ where the old
* RPC password is passwd.
*/
/*ARGSUSED*/
int
{
int res;
char *dn; /* dn of user whose attributes we are changing */
char *binddn; /* dn of user who is performing the change */
int pwd_status;
return (PWU_NOT_FOUND);
/*
* The LDAP server checks whether we are permitted to perform
* the requested change. We need to send the name of the user
* who is executing this piece of code, together with his
* current password to the server.
* password, this will simply be the OLD password that is to
* be changed.
* Specific case if the user who is executing this piece
* of code is root. We will then issue the LDAP request
* with the DN of the user we want to change the passwd of.
*/
/*
* convert name of user whose attributes we are changing
* to a distinguished name
*/
if (res != NS_LDAP_SUCCESS)
goto out;
/*
* create a dn for the user who is executing this code
*/
if (uid == 0) {
goto out;
}
/*
* User executing this code is not known to the LDAP
* server. This operation is to be denied
*/
goto out;
}
if (res != NS_LDAP_SUCCESS)
goto out;
&pwd_status);
out:
while (*attrs) {
attrs++;
}
}
}