/*-
* Copyright (c) 2004 Michael Bushkov <bushman@rsu.ru>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/param.h>
#include <nss.h>
#include <stdlib.h>
#include <errno.h>
#include <ldap.h>
#include <group_defs.h>
#include <passwd_defs.h>
#include <stdlib.h>
#include <string.h>
#include "bsdnss.h"
extern enum nss_status
_nss_ldap_getgrent_r(struct group *, char *, size_t,
int *);
extern enum nss_status
_nss_ldap_getgrnam_r(const char *, struct group *,
char *, size_t, int *);
extern enum nss_status
_nss_ldap_getgrgid_r(gid_t gid, struct group *, char *,
size_t, int *);
extern enum nss_status _nss_ldap_setgrent(void);
extern enum nss_status _nss_ldap_endgrent(void);
extern enum nss_status
_nss_ldap_getpwent_r(struct passwd *, char *, size_t,
int *);
extern enum nss_status
_nss_ldap_getpwnam_r(const char *, struct passwd *,
char *, size_t, int *);
extern enum nss_status
_nss_ldap_getpwuid_r(gid_t gid, struct passwd *, char *,
size_t, int *);
extern enum nss_status _nss_ldap_setpwent(void);
extern enum nss_status _nss_ldap_endpwent(void);
extern void lookupd_set_ldap_euid(uid_t new_uid);
#define GROUP_BUFFER_ALLOC_STEP 512
#define GROUP_BUFFER_MAX_SIZE 8192
#define PASSWD_BUFFER_ALLOC_STEP 512
#define PASSWD_BUFFER_MAX_SIZE 8192
void _util_init_tss_keys();
void _resolve_init_tss_keys();
void _ldap_pwd_init_tss_keys();
void _ldap_nss_init_tss_keys();
void _ldap_grp_init_tss_keys();
void
_init()
{
_util_init_tss_keys();
_resolve_init_tss_keys();
_ldap_pwd_init_tss_keys();
_ldap_nss_init_tss_keys();
_ldap_grp_init_tss_keys();
}
enum nss_status
ldap_getgrnam(struct getgrnam_data * request_data, struct group_result * result_data, int *error)
{
enum nss_status status_code = NS_UNAVAIL;
result_data->grp_buffer_size = GROUP_BUFFER_ALLOC_STEP;
do {
if (result_data->grp_buffer_size != GROUP_BUFFER_ALLOC_STEP) {
free(result_data->grp_buffer);
result_data->grp_buffer_size += GROUP_BUFFER_ALLOC_STEP;
}
result_data->grp_buffer = (char *)malloc(result_data->grp_buffer_size);
memset(result_data->grp_buffer, 0, result_data->grp_buffer_size);
status_code = _nss_ldap_getgrnam_r(request_data->name, &result_data->grp_result, result_data->grp_buffer, result_data->grp_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
} while ((status_code == NS_TRYAGAIN) && (result_data->grp_buffer_size <= GROUP_BUFFER_MAX_SIZE));
return status_code;
}
enum nss_status
ldap_getgrgid(struct getgrgid_data * request_data, struct group_result * result_data, int *error)
{
enum nss_status status_code = NS_UNAVAIL;
result_data->grp_buffer_size = GROUP_BUFFER_ALLOC_STEP;
do {
if (result_data->grp_buffer_size != GROUP_BUFFER_ALLOC_STEP) {
free(result_data->grp_buffer);
result_data->grp_buffer_size += GROUP_BUFFER_ALLOC_STEP;
}
result_data->grp_buffer = (char *)malloc(result_data->grp_buffer_size);
memset(result_data->grp_buffer, 0, result_data->grp_buffer_size);
status_code = _nss_ldap_getgrgid_r(request_data->gid, &result_data->grp_result, result_data->grp_buffer, result_data->grp_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
} while ((status_code == NS_TRYAGAIN) && (result_data->grp_buffer_size <= GROUP_BUFFER_MAX_SIZE));
return status_code;
}
enum nss_status
ldap_getpwnam(struct getpwnam_data * request_data, struct passwd_result * result_data, int *error, uid_t euid)
{
enum nss_status status_code = NS_UNAVAIL;
result_data->pwd_buffer_size = PASSWD_BUFFER_ALLOC_STEP;
do {
if (result_data->pwd_buffer_size != PASSWD_BUFFER_ALLOC_STEP) {
free(result_data->pwd_buffer);
result_data->pwd_buffer_size += PASSWD_BUFFER_ALLOC_STEP;
}
/*
* here is the dirty hack with pw_class field of passwd structure
* it is mapped to the null byte of the buffer
* TODO:
* generally, it should be done in lookupd daemon
*/
result_data->pwd_buffer = (char *)malloc(result_data->pwd_buffer_size+1);
memset(result_data->pwd_buffer, 0, result_data->pwd_buffer_size+1);
status_code = _nss_ldap_getpwnam_r(request_data->name, &result_data->pwd_result, result_data->pwd_buffer+1, result_data->pwd_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
if (status_code==NS_SUCCESS)
result_data->pwd_result.pw_class=result_data->pwd_buffer;
} while ((status_code == NS_TRYAGAIN) && (result_data->pwd_buffer_size <= PASSWD_BUFFER_MAX_SIZE));
return status_code;
}
enum nss_status
ldap_getpwuid(struct getpwuid_data * request_data, struct passwd_result * result_data, int *error, uid_t euid)
{
enum nss_status status_code = NS_UNAVAIL;
result_data->pwd_buffer_size = PASSWD_BUFFER_ALLOC_STEP;
do {
if (result_data->pwd_buffer_size != PASSWD_BUFFER_ALLOC_STEP) {
free(result_data->pwd_buffer);
result_data->pwd_buffer_size += PASSWD_BUFFER_ALLOC_STEP;
}
/*
* here is the dirty hack with pw_class field of passwd structure
* it is mapped to the null byte of the buffer
* TODO:
* generally, it should be done in lookupd daemon
*/
result_data->pwd_buffer = (char *)malloc(result_data->pwd_buffer_size+1);
memset(result_data->pwd_buffer, 0, result_data->pwd_buffer_size+1);
status_code = _nss_ldap_getpwuid_r(request_data->uid, &result_data->pwd_result, result_data->pwd_buffer+1, result_data->pwd_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
if (status_code==NS_SUCCESS)
result_data->pwd_result.pw_class=result_data->pwd_buffer;
} while ((status_code == NS_TRYAGAIN) && (result_data->pwd_buffer_size <= PASSWD_BUFFER_MAX_SIZE));
return status_code;
}
enum nss_status
ldap_getgrent(struct getgrent_data * request_data, struct group_result * result_data, int *error)
{
int cursor_position = 0;
enum nss_status status_code = NS_UNAVAIL;
if (request_data->cursor_size != 0)
cursor_position = *((int *)request_data->cursor_buffer);
else
_nss_ldap_setgrent();
result_data->grp_buffer_size = GROUP_BUFFER_ALLOC_STEP;
do {
if (result_data->grp_buffer_size != GROUP_BUFFER_ALLOC_STEP) {
free(result_data->grp_buffer);
result_data->grp_buffer_size += GROUP_BUFFER_ALLOC_STEP;
}
result_data->grp_buffer = (char *)malloc(result_data->grp_buffer_size);
memset(result_data->grp_buffer, 0, result_data->grp_buffer_size);
status_code = _nss_ldap_getgrent_r(&result_data->grp_result, result_data->grp_buffer, result_data->grp_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
} while ((status_code == NS_TRYAGAIN) && (result_data->grp_buffer_size <= GROUP_BUFFER_MAX_SIZE));
if (status_code == NS_SUCCESS) {
if (request_data->cursor_size == 0)
request_data->cursor_buffer = (int *)malloc(sizeof(int));
*((int *)request_data->cursor_buffer) = cursor_position + 1;
request_data->cursor_size = sizeof(int);
}
return status_code;
}
enum nss_status
ldap_getpwent(struct getpwent_data * request_data, struct passwd_result * result_data, int *error, uid_t euid)
{
int cursor_position = 0;
enum nss_status status_code = NS_UNAVAIL;
if (request_data->cursor_size != 0)
cursor_position = *((int *)request_data->cursor_buffer);
else
_nss_ldap_setpwent();
result_data->pwd_buffer_size = PASSWD_BUFFER_ALLOC_STEP;
do {
if (result_data->pwd_buffer_size != PASSWD_BUFFER_ALLOC_STEP) {
free(result_data->pwd_buffer);
result_data->pwd_buffer_size += PASSWD_BUFFER_ALLOC_STEP;
}
/*
* here is the dirty hack with pw_class field of passwd structure
* it is mapped to the null byte of the buffer
* TODO:
* generally, it should be done in lookupd daemon
*/
result_data->pwd_buffer = (char *)malloc(result_data->pwd_buffer_size+1);
memset(result_data->pwd_buffer, 0, result_data->pwd_buffer_size+1);
status_code = _nss_ldap_getpwent_r(&result_data->pwd_result, result_data->pwd_buffer+1, result_data->pwd_buffer_size, error);
status_code = __nss_compat_result(status_code, *error);
if (status_code==NS_SUCCESS)
result_data->pwd_result.pw_class=result_data->pwd_buffer;
} while ((status_code == NS_TRYAGAIN) && (result_data->pwd_buffer_size <= PASSWD_BUFFER_MAX_SIZE));
if (status_code == NS_SUCCESS) {
if (request_data->cursor_size == 0)
request_data->cursor_buffer = (int *)malloc(sizeof(int));
*((int *)request_data->cursor_buffer) = cursor_position + 1;
request_data->cursor_size = sizeof(int);
}
return status_code;
}
syntax highlighted by Code2HTML, v. 0.9.1