/*- * Copyright (c) 2004 Michael Bushkov * 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 #include #include #include #include #include #include #include #include #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; }