xref: /netbsd-src/external/bsd/cron/dist/pw_dup.c (revision 032a439890ddfa3f6f4a2803c19869bfa3a6ad0e)
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