/* Copyright (c) 2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ /** @file uabesys.c System backend. */ /** In the uabesys module. */ #define UABESYS_C 1 #include "useraudi.h" $(trace-include) /** Retrieve information about a user account. @param uac UAC structure. @param uab Backend to ask. @param a API structure to communicate to backend. */ static void find_user DK_P3(UAC *,uac, UAB *,uab, UAB_API *,a) { struct passwd *pw = NULL; struct spwd *sp = NULL; struct group *gr; UAU *u = NULL; int have_error = 0; int cc; int ingroup; char **grmemptr; UAG *ge; char *x; $? "+ find_user" pw = uat_getpwnam((a->a).v); if(pw) { $? ". pw entry ok" sp = uat_getspnam((a->a).v); if(sp) { $? ". shadow entry ok" if(sp->sp_pwdp) { $? ". password hash available" u = uau_new((a->a).v); if(u) { $? ". UAU allocated" u->pw_hash = dkstr_dup(sp->sp_pwdp); u->ht = uab->ht; u->st = uab->st; u->sl = uab->sl; if((u->user_name) && (u->pw_hash)) { $? ". pw hash allocated" x = dkstr_chr(u->pw_hash, ','); if(x) { *x = '\0'; } if(u->ht == USERAUD_HASH_CRYPT) { $? ". correct salt length" uatcs_correct_crypt_st_sl(uac, &(u->st), &(u->sl), u->pw_hash); } if(((a->a).f) & 1) { $? ". detailed search (start)" u->uid = pw->pw_uid; if(pw->pw_gecos) { $? ". keep gecos" u->gecos = dkstr_dup(pw->pw_gecos); if(!(u->gecos)) { $? "! memory" have_error = 1; } } u->primary_group = pw->pw_gid; #if DK_HAVE_GETGRENT $? ". before traversing groups" #if DK_HAVE_SETGRENT setgrent(); #endif cc = 1; while(cc && useraud_get_outer_loop()) { cc = 0; gr = getgrent(); if(gr) { $? ". group found" cc = 1; if(gr->gr_gid == u->primary_group) { $? ". primary group" if(gr->gr_name) { if(u->pg_name) { x = u->pg_name; dk_delete(x); u->pg_name = NULL; } u->pg_name = dkstr_dup(gr->gr_name); if(!(u->pg_name)) { have_error = 1; } } } else { $? ". not primary group" ingroup = 0; if(gr->gr_mem) { grmemptr = gr->gr_mem; while((ingroup == 0) && (*grmemptr)) { $? "\"%s\"<=>\"%s\"", (a->a).v, *grmemptr if(strcmp((a->a).v, *grmemptr) == 0) { ingroup = 1; $? ". in group" } grmemptr++; } } if(ingroup) { $? ". in group" if(gr->gr_name) { if(!(u->s_g)) { u->s_g = dksto_open(0); if(u->s_g) { u->i_g = dksto_it_open(u->s_g); if(!(u->i_g)) have_error = 1; } else { have_error = 1; } } if((u->s_g) && (u->i_g)) { $? ". save group" ge = uau_group_new(gr->gr_name, gr->gr_gid); if(ge) { $? ". allocated" if(!dksto_add(u->s_g, (void *)ge)) { $? "! memory" uau_group_delete(ge); ge = NULL; have_error = 1; } } } } } } } } #ifdef DK_HAVE_SETGRENT endgrent(); #endif $? ". after traversing groups" #endif if(have_error) { uau_delete(u); } else { (a->r).s = 0x01; (a->r).ec = 0; (a->r).u = u; } $? ". detailed search (end)" } else { $? ". no detailed search necessary" (a->r).s = 0x01; (a->r).ec = 0; (a->r).u = u; } } else { $? "! memory" uau_delete(u); } } else { $? "! memory" } } else { $? "! no password hash" } } else { $? "! no shadow entry" } } else { $? "! no such user" } $? "- find_user %d", (int)((a->r).s) } /** The system backend function. @param uac UAC structure. @param bevp Backend pointer casted to (void *). @param a API for communication between useraud and backend. */ void uabesys DK_P3(UAC *,uac, void *,bevp, UAB_API *,a) { UAB *uab; uab = (UAB *)bevp; $? "+ uabesys %s %s %s", TR_PTR(uac), TR_PTR(uab), TR_PTR(a) if(a) { (a->r).s = 0x00; (a->r).ec = UA_ERROR_INTERNAL; (a->r).u = NULL; if((a->a).c == UA_API_AVAILABLE) { $? ". UA_API_AVAILABLE" (a->r).s = 0x01; } else { if((uac) && (uab)) { switch((a->a).c) { case UA_API_CREATE_DATA: { $? ". UA_API_CREATE_DATA" (a->r).s = 0x01; (a->r).ec = 0; } break; case UA_API_DESTROY_DATA: { $? ". UA_API_DESTROY_DATA" (a->r).s = 0x01; (a->r).ec = 0; } break; case UA_API_CHECK_CONFIG: { $? ". UA_API_CHECK_CONFIG" (a->r).s = 0x01; (a->r).ec = 0; } break; case UA_API_CONFLINE: { $? ". UA_API_CONFLINE" (a->r).ec = UA_ERROR_SYNTAX; /* Nothing to configure. */ } break; case UA_API_GET_USER: { $? ". UA_API_GET_USER" find_user(uac, uab, a); } break; } } } } $? "- uabesys %u", (unsigned)((a->r).s) }