885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/*
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Unix SMB/CIFS implementation.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Winbind client API - SSSD version
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Copyright (C) Sumit Bose <sbose@redhat.com> 2014
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose This library is free software; you can redistribute it and/or
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose modify it under the terms of the GNU Lesser General Public
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose License as published by the Free Software Foundation; either
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose version 3 of the License, or (at your option) any later version.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose This library is distributed in the hope that it will be useful,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose Library General Public License for more details.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose You should have received a copy of the GNU Lesser General Public License
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose*/
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Required Headers */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include <nss.h>
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include <dlfcn.h>
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include <errno.h>
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include "libwbclient.h"
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#include "wbc_sssd_internal.h"
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#define DEFAULT_BUFSIZE_HALF 2048
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#define DEFAULT_BUFSIZE (2 * DEFAULT_BUFSIZE_HALF)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose#define MAX_BUFSIZE (1024*1204)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestruct nss_ops_ctx {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose void *dl_handle;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*setpwent)(void);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getpwent_r)(struct passwd *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*endpwent)(void);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getgrnam_r)(const char *name, struct group *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*setgrent)(void);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*getgrent_r)(struct group *result,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer, size_t buflen, int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*endgrent)(void);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose long int *start, long int *size,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gid_t **groups, long int limit,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int *errnop);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose};
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestruct nss_ops_ctx *ctx = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic bool open_libnss_sss(void)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx = calloc(1, sizeof(struct nss_ops_ctx));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return false;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->dl_handle == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getpwnam_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getpwuid_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->setpwent = dlsym(ctx->dl_handle, "_nss_sss_setpwent");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->setpwent == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getpwent_r = dlsym(ctx->dl_handle, "_nss_sss_getpwent_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getpwent_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->endpwent = dlsym(ctx->dl_handle, "_nss_sss_endpwent");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->endpwent == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getgrnam_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getgrgid_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->setgrent = dlsym(ctx->dl_handle, "_nss_sss_setgrent");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->setgrent == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->getgrent_r = dlsym(ctx->dl_handle, "_nss_sss_getgrent_r");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->getgrent_r == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->endgrent = dlsym(ctx->dl_handle, "_nss_sss_endgrent");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->endgrent == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn");
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->initgroups_dyn == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return true;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosefail:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx->dl_handle != NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose dlclose(ctx->dl_handle);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(ctx);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose ctx = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return false;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic void wbcPasswdDestructor(void *ptr)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd *pw = (struct passwd *)ptr;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(pw->pw_name);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(pw->pw_passwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(pw->pw_gecos);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(pw->pw_shell);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(pw->pw_dir);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic wbcErr copy_pwd(struct passwd *in, struct passwd **out)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd *pw;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw = (struct passwd *)wbcAllocateMemory(1, sizeof(struct passwd),
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcPasswdDestructor);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_name = strdup(in->pw_name);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw->pw_name == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_passwd = strdup(in->pw_passwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw->pw_passwd == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_uid = in->pw_uid;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_gid = in->pw_gid;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_gecos = strdup(in->pw_gecos);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw->pw_gecos == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_shell = strdup(in->pw_shell);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw->pw_shell == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose pw->pw_dir = strdup(in->pw_dir);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pw->pw_dir == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose *out = pw;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosefail:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcFreeMemory(pw);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic wbcErr nss_to_wbc(enum nss_status status)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose switch (status) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case NSS_STATUS_SUCCESS:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose break;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case NSS_STATUS_NOTFOUND:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_UNKNOWN_USER;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose break;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose case NSS_STATUS_UNAVAIL:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose break;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose default:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_UNKNOWN_FAILURE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Fill in a struct passwd* for a domain user based on username */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetpwnam(const char *name, struct passwd **pwd)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd lpwd = {0};
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (name == NULL || pwd == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = malloc(buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (buffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getpwnam_r(name, &lpwd, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_pwd(&lpwd, pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Fill in a struct passwd* for a domain user based on uid */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd lpwd = {0};
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pwd == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = malloc(buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (buffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getpwuid_r(uid, &lpwd, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_pwd(&lpwd, pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Fill in a struct passwd* for a domain user based on sid */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose uid_t uid;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = wbcSidToUid(sid, &uid);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!WBC_ERROR_IS_OK(wbc_status)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = wbcGetpwuid(uid, pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic void wbcGroupDestructor(void *ptr)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct group *gr = (struct group *)ptr;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t c;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(gr->gr_name);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(gr->gr_passwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* if the array was partly created this can be NULL */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr->gr_mem == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose for (c=0; gr->gr_mem[c] != NULL; c++) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(gr->gr_mem[c]);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(gr->gr_mem);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosestatic wbcErr copy_grp(struct group *in, struct group **out)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct group *gr;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t members;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t c;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr = (struct group *)wbcAllocateMemory(1, sizeof(struct group),
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcGroupDestructor);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr->gr_name = strdup(in->gr_name);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr->gr_name == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr->gr_passwd = strdup(in->gr_passwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr->gr_passwd == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr->gr_gid = in->gr_gid;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose for (members = 0; in->gr_mem[members] != NULL; members++);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr->gr_mem = (char **)calloc(members+1, sizeof(char *));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr->gr_mem == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose for (c = 0; c < members; c++) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr->gr_mem[c] = strdup(in->gr_mem[c]);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gr->gr_mem[c] == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto fail;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose *out = gr;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosefail:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcFreeMemory(gr);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Fill in a struct passwd* for a domain user based on username */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetgrnam(const char *name, struct group **grp)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct group lgrp;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *newbuffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (name == NULL || grp == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE_HALF;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose do {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen *= 2;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose newbuffer = realloc(buffer, buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (newbuffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = newbuffer;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose memset(grp, 0, sizeof(struct group));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getgrnam_r(name, &lgrp, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_grp(&lgrp, grp);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose && buflen < MAX_BUFSIZE);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Fill in a struct passwd* for a domain user based on uid */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetgrgid(gid_t gid, struct group **grp)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct group lgrp;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *newbuffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (grp == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE_HALF;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose do {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen *= 2;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose newbuffer = realloc(buffer, buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (newbuffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = newbuffer;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose memset(grp, 0, sizeof(struct group));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getgrgid_r(gid, &lgrp, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_grp(&lgrp, grp);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose && buflen < MAX_BUFSIZE);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Reset the passwd iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcSetpwent(void)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->setpwent();
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Close the passwd iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcEndpwent(void)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->endpwent();
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Return the next struct passwd* entry from the pwent iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetpwent(struct passwd **pwd)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd lpwd = {0};
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (pwd == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = malloc(buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (buffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getpwent_r(&lpwd, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_pwd(&lpwd, pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Reset the group iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcSetgrent(void)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->setgrent();
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Close the group iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcEndgrent(void)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->endgrent();
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Return the next struct group* entry from the pwent iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetgrent(struct group **grp)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct group lgrp;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *newbuffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose char *buffer = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose size_t buflen = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (ctx == NULL && !open_libnss_sss()) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NSS_ERROR;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (grp == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_INVALID_PARAM;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen = DEFAULT_BUFSIZE_HALF;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose do {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buflen *= 2;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose newbuffer = realloc(buffer, buflen);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (newbuffer == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose buffer = newbuffer;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose memset(grp, 0, sizeof(struct group));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->getgrent_r(&lgrp, buffer, buflen, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WBC_ERROR_IS_OK(wbc_status) == true) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = copy_grp(&lgrp, grp);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose && buflen < MAX_BUFSIZE);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(buffer);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Return the next struct group* entry from the pwent iterator */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetgrlist(struct group **grp)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* Not used anywhere */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose WBC_SSSD_NOT_IMPLEMENTED;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose/* Return the unix group array belonging to the given user */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit BosewbcErr wbcGetGroups(const char *account,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose uint32_t *num_groups,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gid_t **_groups)
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose{
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcErr wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose enum nss_status status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose struct passwd *pwd;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose long int gr_size = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose long int start = 0;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gid_t *gids = NULL;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose int nss_errno;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = wbcGetpwnam(account, &pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!WBC_ERROR_IS_OK(wbc_status)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gr_size = DEFAULT_BUFSIZE;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gids = calloc(gr_size, sizeof(gid_t));
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (gids == NULL) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_NO_MEMORY;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto done;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose /* nss modules may skip the primary group when we pass it in so always
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose * add it in advance */
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose gids[0] = pwd->pw_gid;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose start++;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose status = ctx->initgroups_dyn(pwd->pw_name, pwd->pw_gid, &start,
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose &gr_size, &gids, -1, &nss_errno);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = nss_to_wbc(status);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!WBC_ERROR_IS_OK(wbc_status)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose goto done;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose *_groups = gids;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose *num_groups = start;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbc_status = WBC_ERR_SUCCESS;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bosedone:
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose wbcFreeMemory(pwd);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose if (!WBC_ERROR_IS_OK(wbc_status)) {
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose free(gids);
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose }
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose return wbc_status;
885386b7e3f1c3e74b354576b98a092b0835d64eSumit Bose}