group.c revision 194104
1158115Sume/*- 2158115Sume * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 3158115Sume * All rights reserved. 4158115Sume * 5158115Sume * Redistribution and use in source and binary forms, with or without 6158115Sume * modification, are permitted provided that the following conditions 7158115Sume * are met: 8158115Sume * 1. Redistributions of source code must retain the above copyright 9158115Sume * notice, this list of conditions and the following disclaimer. 10158115Sume * 2. Redistributions in binary form must reproduce the above copyright 11158115Sume * notice, this list of conditions and the following disclaimer in the 12158115Sume * documentation and/or other materials provided with the distribution. 13158115Sume * 14158115Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15158115Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16158115Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17158115Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18158115Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19158115Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20158115Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21158115Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22158115Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23158115Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24158115Sume * SUCH DAMAGE. 25158115Sume * 26158115Sume */ 27158115Sume 28158115Sume#include <sys/cdefs.h> 29158115Sume__FBSDID("$FreeBSD: head/usr.sbin/nscd/agents/group.c 194104 2009-06-13 13:07:56Z des $"); 30158115Sume 31158115Sume#include <sys/param.h> 32194093Sdes 33158115Sume#include <assert.h> 34194093Sdes#include <grp.h> 35158115Sume#include <nsswitch.h> 36194093Sdes#include <stdlib.h> 37158115Sume#include <string.h> 38194093Sdes 39158115Sume#include "../debug.h" 40194094Sdes#include "group.h" 41158115Sume 42158115Sumestatic int group_marshal_func(struct group *, char *, size_t *); 43158115Sumestatic int group_lookup_func(const char *, size_t, char **, size_t *); 44194087Sdesstatic void *group_mp_init_func(void); 45158115Sumestatic int group_mp_lookup_func(char **, size_t *, void *); 46158115Sumestatic void group_mp_destroy_func(void *); 47158115Sume 48158115Sumestatic int 49158115Sumegroup_marshal_func(struct group *grp, char *buffer, size_t *buffer_size) 50158115Sume{ 51158115Sume struct group new_grp; 52158115Sume size_t desired_size, size, mem_size; 53158115Sume char *p, **mem; 54158115Sume 55158115Sume TRACE_IN(group_marshal_func); 56158115Sume desired_size = ALIGNBYTES + sizeof(struct group) + sizeof(char *); 57158115Sume 58158115Sume if (grp->gr_name != NULL) 59158115Sume desired_size += strlen(grp->gr_name) + 1; 60158115Sume if (grp->gr_passwd != NULL) 61158115Sume desired_size += strlen(grp->gr_passwd) + 1; 62158115Sume 63158115Sume if (grp->gr_mem != NULL) { 64158115Sume mem_size = 0; 65158115Sume for (mem = grp->gr_mem; *mem; ++mem) { 66158115Sume desired_size += strlen(*mem) + 1; 67158115Sume ++mem_size; 68158115Sume } 69158115Sume 70158115Sume desired_size += ALIGNBYTES + (mem_size + 1) * sizeof(char *); 71158115Sume } 72158115Sume 73158115Sume if ((desired_size > *buffer_size) || (buffer == NULL)) { 74158115Sume *buffer_size = desired_size; 75158115Sume TRACE_OUT(group_marshal_func); 76158115Sume return (NS_RETURN); 77158115Sume } 78158115Sume 79158115Sume memcpy(&new_grp, grp, sizeof(struct group)); 80158115Sume memset(buffer, 0, desired_size); 81158115Sume 82158115Sume *buffer_size = desired_size; 83158115Sume p = buffer + sizeof(struct group) + sizeof(char *); 84158115Sume memcpy(buffer + sizeof(struct group), &p, sizeof(char *)); 85158115Sume p = (char *)ALIGN(p); 86158115Sume 87158115Sume if (new_grp.gr_name != NULL) { 88158115Sume size = strlen(new_grp.gr_name); 89158115Sume memcpy(p, new_grp.gr_name, size); 90158115Sume new_grp.gr_name = p; 91158115Sume p += size + 1; 92158115Sume } 93158115Sume 94158115Sume if (new_grp.gr_passwd != NULL) { 95158115Sume size = strlen(new_grp.gr_passwd); 96158115Sume memcpy(p, new_grp.gr_passwd, size); 97158115Sume new_grp.gr_passwd = p; 98158115Sume p += size + 1; 99158115Sume } 100158115Sume 101158115Sume if (new_grp.gr_mem != NULL) { 102158115Sume p = (char *)ALIGN(p); 103158115Sume memcpy(p, new_grp.gr_mem, sizeof(char *) * mem_size); 104158115Sume new_grp.gr_mem = (char **)p; 105158115Sume p += sizeof(char *) * (mem_size + 1); 106158115Sume 107158115Sume for (mem = new_grp.gr_mem; *mem; ++mem) { 108158115Sume size = strlen(*mem); 109158115Sume memcpy(p, *mem, size); 110158115Sume *mem = p; 111158115Sume p += size + 1; 112158115Sume } 113158115Sume } 114158115Sume 115158115Sume memcpy(buffer, &new_grp, sizeof(struct group)); 116158115Sume TRACE_OUT(group_marshal_func); 117158115Sume return (NS_SUCCESS); 118158115Sume} 119158115Sume 120158115Sumestatic int 121158115Sumegroup_lookup_func(const char *key, size_t key_size, char **buffer, 122158115Sume size_t *buffer_size) 123158115Sume{ 124158115Sume enum nss_lookup_type lookup_type; 125158115Sume char *name; 126158115Sume size_t size; 127158115Sume gid_t gid; 128158115Sume 129158115Sume struct group *result; 130158115Sume 131158115Sume TRACE_IN(group_lookup_func); 132158115Sume assert(buffer != NULL); 133158115Sume assert(buffer_size != NULL); 134158115Sume 135158115Sume if (key_size < sizeof(enum nss_lookup_type)) { 136158115Sume TRACE_OUT(group_lookup_func); 137158115Sume return (NS_UNAVAIL); 138158115Sume } 139158115Sume memcpy(&lookup_type, key, sizeof(enum nss_lookup_type)); 140158115Sume 141158115Sume switch (lookup_type) { 142158115Sume case nss_lt_name: 143158115Sume size = key_size - sizeof(enum nss_lookup_type) + 1; 144194104Sdes name = calloc(1, size); 145158115Sume assert(name != NULL); 146158115Sume memcpy(name, key + sizeof(enum nss_lookup_type), size - 1); 147158115Sume break; 148158115Sume case nss_lt_id: 149158115Sume if (key_size < sizeof(enum nss_lookup_type) + 150158115Sume sizeof(gid_t)) { 151158115Sume TRACE_OUT(passwd_lookup_func); 152158115Sume return (NS_UNAVAIL); 153158115Sume } 154158115Sume 155158115Sume memcpy(&gid, key + sizeof(enum nss_lookup_type), sizeof(gid_t)); 156158115Sume break; 157158115Sume default: 158158115Sume TRACE_OUT(group_lookup_func); 159158115Sume return (NS_UNAVAIL); 160158115Sume } 161158115Sume 162158115Sume switch (lookup_type) { 163158115Sume case nss_lt_name: 164158115Sume TRACE_STR(name); 165158115Sume result = getgrnam(name); 166158115Sume free(name); 167158115Sume break; 168158115Sume case nss_lt_id: 169158115Sume result = getgrgid(gid); 170158115Sume break; 171158115Sume default: 172158115Sume /* SHOULD NOT BE REACHED */ 173158115Sume break; 174158115Sume } 175158115Sume 176158115Sume if (result != NULL) { 177158115Sume group_marshal_func(result, NULL, buffer_size); 178194104Sdes *buffer = malloc(*buffer_size); 179158115Sume assert(*buffer != NULL); 180158115Sume group_marshal_func(result, *buffer, buffer_size); 181158115Sume } 182158115Sume 183158115Sume TRACE_OUT(group_lookup_func); 184158115Sume return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); 185158115Sume} 186158115Sume 187158115Sumestatic void * 188194087Sdesgroup_mp_init_func(void) 189158115Sume{ 190158115Sume TRACE_IN(group_mp_init_func); 191158115Sume setgrent(); 192158115Sume TRACE_OUT(group_mp_init_func); 193158115Sume 194158115Sume return (NULL); 195158115Sume} 196158115Sume 197158115Sumestatic int 198158115Sumegroup_mp_lookup_func(char **buffer, size_t *buffer_size, void *mdata) 199158115Sume{ 200158115Sume struct group *result; 201158115Sume 202158115Sume TRACE_IN(group_mp_lookup_func); 203158115Sume result = getgrent(); 204158115Sume if (result != NULL) { 205158115Sume group_marshal_func(result, NULL, buffer_size); 206194104Sdes *buffer = malloc(*buffer_size); 207158115Sume assert(*buffer != NULL); 208158115Sume group_marshal_func(result, *buffer, buffer_size); 209158115Sume } 210158115Sume 211158115Sume TRACE_OUT(group_mp_lookup_func); 212158115Sume return (result == NULL ? NS_NOTFOUND : NS_SUCCESS); 213158115Sume} 214158115Sume 215158115Sumestatic void 216158115Sumegroup_mp_destroy_func(void *mdata) 217158115Sume{ 218158115Sume TRACE_IN(group_mp_destroy_func); 219158115Sume TRACE_OUT(group_mp_destroy_func); 220158115Sume} 221158115Sume 222158115Sumestruct agent * 223194087Sdesinit_group_agent(void) 224158115Sume{ 225158115Sume struct common_agent *retval; 226158115Sume 227158115Sume TRACE_IN(init_group_agent); 228194104Sdes retval = calloc(1, sizeof(*retval)); 229158115Sume assert(retval != NULL); 230158115Sume 231158115Sume retval->parent.name = strdup("group"); 232158115Sume assert(retval->parent.name != NULL); 233158115Sume 234158115Sume retval->parent.type = COMMON_AGENT; 235158115Sume retval->lookup_func = group_lookup_func; 236158115Sume 237158115Sume TRACE_OUT(init_group_agent); 238158115Sume return ((struct agent *)retval); 239158115Sume} 240158115Sume 241158115Sumestruct agent * 242194087Sdesinit_group_mp_agent(void) 243158115Sume{ 244158115Sume struct multipart_agent *retval; 245158115Sume 246158115Sume TRACE_IN(init_group_mp_agent); 247194104Sdes retval = calloc(1, 248194104Sdes sizeof(*retval)); 249158115Sume assert(retval != NULL); 250158115Sume 251158115Sume retval->parent.name = strdup("group"); 252158115Sume retval->parent.type = MULTIPART_AGENT; 253158115Sume retval->mp_init_func = group_mp_init_func; 254158115Sume retval->mp_lookup_func = group_mp_lookup_func; 255158115Sume retval->mp_destroy_func = group_mp_destroy_func; 256158115Sume assert(retval->parent.name != NULL); 257158115Sume 258158115Sume TRACE_OUT(init_group_mp_agent); 259158115Sume return ((struct agent *)retval); 260158115Sume} 261