1 /*
2 * Copyright (c) 2000,2002 Todd C. Miller <Todd.Miller@courtesan.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
9 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
11 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 /*
18 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
19 *
20 * Permission to use, copy, modify, and distribute this software for any
21 * purpose with or without fee is hereby granted, provided that the above
22 * copyright notice and this permission notice appear in all copies.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
25 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
27 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
30 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 */
32 #include <sys/cdefs.h>
33 #if !defined(lint) && !defined(LINT)
34 #if 0
35 static char rcsid[] = "Id: pw_dup.c,v 1.2 2004/01/23 18:56:43 vixie Exp";
36 #else
37 __RCSID("$NetBSD: pw_dup.c,v 1.2 2010/05/06 18:53:17 christos Exp $");
38 #endif
39 #endif
40
41 #include <sys/param.h>
42
43 #if !defined(OpenBSD) || OpenBSD < 200105
44
45 #include <pwd.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <bitstring.h>
50
51 #include "config.h"
52 #include "macros.h"
53 #include "structs.h"
54 #include "funcs.h"
55
56 struct passwd *
pw_dup(const struct passwd * pw)57 pw_dup(const struct passwd *pw) {
58 char *cp;
59 size_t nsize, psize, gsize, dsize, ssize, total;
60 #ifdef LOGIN_CAP
61 size_t csize;
62 #endif
63 struct passwd *newpw;
64
65 /* Allocate in one big chunk for easy freeing */
66 total = sizeof(struct passwd);
67 if (pw->pw_name) {
68 nsize = strlen(pw->pw_name) + 1;
69 total += nsize;
70 } else
71 nsize = 0;
72 if (pw->pw_passwd) {
73 psize = strlen(pw->pw_passwd) + 1;
74 total += psize;
75 } else
76 psize = 0;
77 #ifdef LOGIN_CAP
78 if (pw->pw_class) {
79 csize = strlen(pw->pw_class) + 1;
80 total += csize;
81 } else
82 csize = 0;
83 #endif /* LOGIN_CAP */
84 if (pw->pw_gecos) {
85 gsize = strlen(pw->pw_gecos) + 1;
86 total += gsize;
87 } else
88 gsize = 0;
89 if (pw->pw_dir) {
90 dsize = strlen(pw->pw_dir) + 1;
91 total += dsize;
92 } else
93 dsize = 0;
94 if (pw->pw_shell) {
95 ssize = strlen(pw->pw_shell) + 1;
96 total += ssize;
97 } else
98 ssize = 0;
99 if ((newpw = malloc(total)) == NULL)
100 return (NULL);
101 cp = (char *)(void *)newpw;
102
103 /*
104 * Copy in passwd contents and make strings relative to space
105 * at the end of the buffer.
106 */
107 (void)memcpy(newpw, pw, sizeof(struct passwd));
108 cp += sizeof(struct passwd);
109 if (pw->pw_name) {
110 (void)memcpy(cp, pw->pw_name, nsize);
111 newpw->pw_name = cp;
112 cp += nsize;
113 }
114 if (pw->pw_passwd) {
115 (void)memcpy(cp, pw->pw_passwd, psize);
116 newpw->pw_passwd = cp;
117 cp += psize;
118 }
119 #ifdef LOGIN_CAP
120 if (pw->pw_class) {
121 (void)memcpy(cp, pw->pw_class, csize);
122 newpw->pw_class = cp;
123 cp += csize;
124 }
125 #endif /* LOGIN_CAP */
126 if (pw->pw_gecos) {
127 (void)memcpy(cp, pw->pw_gecos, gsize);
128 newpw->pw_gecos = cp;
129 cp += gsize;
130 }
131 if (pw->pw_dir) {
132 (void)memcpy(cp, pw->pw_dir, dsize);
133 newpw->pw_dir = cp;
134 cp += dsize;
135 }
136 if (pw->pw_shell) {
137 (void)memcpy(cp, pw->pw_shell, ssize);
138 newpw->pw_shell = cp;
139 cp += ssize;
140 }
141
142 return (newpw);
143 }
144
145 #endif /* !OpenBSD || OpenBSD < 200105 */
146