Line data Source code
1 : /* 2 : * BSD 3-Clause License 3 : * 4 : * Copyright (c) 2007, Stefan Metzmacher <metze@samba.org> 5 : * Copyright (c) 2009, Guenther Deschner <gd@samba.org> 6 : * Copyright (c) 2014-2015, Michael Adam <obnox@samba.org> 7 : * Copyright (c) 2015, Robin Hack <hack.robin@gmail.com> 8 : * Copyright (c) 2013-2018, Andreas Schneider <asn@samba.org> 9 : * All rights reserved. 10 : * 11 : * Redistribution and use in source and binary forms, with or without 12 : * modification, are permitted provided that the following conditions 13 : * are met: 14 : * 15 : * 1. Redistributions of source code must retain the above copyright 16 : * notice, this list of conditions and the following disclaimer. 17 : * 18 : * 2. Redistributions in binary form must reproduce the above copyright 19 : * notice, this list of conditions and the following disclaimer in the 20 : * documentation and/or other materials provided with the distribution. 21 : * 22 : * 3. Neither the name of the author nor the names of its contributors 23 : * may be used to endorse or promote products derived from this software 24 : * without specific prior written permission. 25 : * 26 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 : * SUCH DAMAGE. 37 : */ 38 : 39 : #include <errno.h> 40 : #include <grp.h> 41 : #include <string.h> 42 : #include <stdint.h> 43 : 44 : #include "nss_utils.h" 45 : 46 5035 : int nwrap_gr_copy_r(const struct group *src, struct group *dst, 47 : char *buf, size_t buflen, struct group **dstp) 48 : { 49 5035 : char *p = NULL; 50 5035 : uintptr_t align = 0; 51 5035 : unsigned int gr_mem_cnt = 0; 52 2 : unsigned i; 53 2 : size_t total_len; 54 5035 : size_t gr_name_len = strlen(src->gr_name) + 1; 55 5035 : size_t gr_passwd_len = strlen(src->gr_passwd) + 1; 56 2 : union { 57 : char *ptr; 58 : char **data; 59 : } g_mem; 60 : 61 5179 : for (i = 0; src->gr_mem[i] != NULL; i++) { 62 144 : gr_mem_cnt++; 63 : } 64 : 65 : /* Align the memory for storing pointers */ 66 5035 : align = __alignof__(char *) - ((p - (char *)0) % __alignof__(char *)); 67 5035 : total_len = align + 68 5035 : (1 + gr_mem_cnt) * sizeof(char *) + 69 : gr_name_len + gr_passwd_len; 70 : 71 5035 : if (total_len > buflen) { 72 0 : errno = ERANGE; 73 0 : return -1; 74 : } 75 5035 : buflen -= total_len; 76 : 77 : /* gr_mem */ 78 5035 : p = buf + align; 79 5035 : g_mem.ptr = p; 80 5035 : dst->gr_mem = g_mem.data; 81 : 82 : /* gr_name */ 83 5035 : p += (1 + gr_mem_cnt) * sizeof(char *); 84 5035 : dst->gr_name = p; 85 : 86 : /* gr_passwd */ 87 5035 : p += gr_name_len; 88 5035 : dst->gr_passwd = p; 89 : 90 : /* gr_mem[x] */ 91 5035 : p += gr_passwd_len; 92 : 93 : /* gr_gid */ 94 5035 : dst->gr_gid = src->gr_gid; 95 : 96 5035 : memcpy(dst->gr_name, src->gr_name, gr_name_len); 97 : 98 5035 : memcpy(dst->gr_passwd, src->gr_passwd, gr_passwd_len); 99 : 100 : /* Set the terminating entry */ 101 5035 : dst->gr_mem[gr_mem_cnt] = NULL; 102 : 103 : /* Now add the group members content */ 104 5035 : total_len = 0; 105 5179 : for (i = 0; i < gr_mem_cnt; i++) { 106 144 : size_t len = strlen(src->gr_mem[i]) + 1; 107 : 108 144 : dst->gr_mem[i] = p; 109 144 : total_len += len; 110 144 : p += len; 111 : } 112 : 113 5035 : if (total_len > buflen) { 114 0 : errno = ERANGE; 115 0 : return -1; 116 : } 117 : 118 5179 : for (i = 0; i < gr_mem_cnt; i++) { 119 144 : size_t len = strlen(src->gr_mem[i]) + 1; 120 : 121 144 : memcpy(dst->gr_mem[i], 122 144 : src->gr_mem[i], 123 : len); 124 : } 125 : 126 5035 : if (dstp != NULL) { 127 5035 : *dstp = dst; 128 : } 129 : 130 5033 : return 0; 131 : }