259649a064e210a744723912ea89f5b6f8933bd5
[ira/wip.git] / source3 / lib / util_pw.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Safe versions of getpw* calls
5
6    Copyright (C) Andrew Bartlett 2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 struct passwd *make_modifyable_passwd(const struct passwd *from)
26 {
27         struct passwd *ret = smb_xmalloc(sizeof(*ret));
28 /*  This is the assumed shape of the members by certain parts of the code...
29         fstring         pw_name;
30         fstring         pw_passwd;
31         fstring         pw_gecos;
32         pstring         pw_dir;
33         pstring         pw_shell;
34 */
35         char *pw_name = smb_xmalloc(sizeof(fstring));
36         char *pw_passwd = smb_xmalloc(sizeof(fstring));
37         char *pw_gecos = smb_xmalloc(sizeof(fstring));
38         char *pw_dir = smb_xmalloc(sizeof(pstring));
39         char *pw_shell = smb_xmalloc(sizeof(pstring));
40
41         ZERO_STRUCTP(ret);
42
43         /* 
44          * Now point the struct's members as the 
45          * newly allocated buffers:
46          */
47
48         ret->pw_name = pw_name;
49         fstrcpy(ret->pw_name, from->pw_name);
50
51         ret->pw_passwd = pw_passwd;
52         fstrcpy(ret->pw_passwd, from->pw_passwd);
53
54         ret->pw_uid = from->pw_uid;
55         ret->pw_gid = from->pw_gid;
56
57         ret->pw_gecos = pw_gecos;
58         fstrcpy(ret->pw_gecos, from->pw_gecos);
59
60         ret->pw_dir = pw_dir;
61         pstrcpy(ret->pw_dir, from->pw_dir);
62
63         ret->pw_shell = pw_shell;
64         pstrcpy(ret->pw_shell, from->pw_shell);
65
66         return ret;
67 }
68
69 static struct passwd *alloc_copy_passwd(const struct passwd *from) 
70 {
71         struct passwd *ret = smb_xmalloc(sizeof(struct passwd));
72         ZERO_STRUCTP(ret);
73         ret->pw_name = smb_xstrdup(from->pw_name);
74         ret->pw_passwd = smb_xstrdup(from->pw_passwd);
75         ret->pw_uid = from->pw_uid;
76         ret->pw_gid = from->pw_gid;
77         ret->pw_gecos = smb_xstrdup(from->pw_gecos);
78         ret->pw_dir = smb_xstrdup(from->pw_dir);
79         ret->pw_shell = smb_xstrdup(from->pw_shell);
80         return ret;
81 }
82
83 void passwd_free (struct passwd **buf)
84 {
85         if (!*buf) {
86                 DEBUG(0, ("attempted double-free of allocated passwd\n"));
87                 return;
88         }
89
90         SAFE_FREE((*buf)->pw_name);
91         SAFE_FREE((*buf)->pw_passwd);
92         SAFE_FREE((*buf)->pw_gecos);
93         SAFE_FREE((*buf)->pw_dir);
94         SAFE_FREE((*buf)->pw_shell);
95
96         SAFE_FREE(*buf);
97 }
98
99 struct passwd *getpwnam_alloc(const char *name) 
100 {
101         struct passwd *temp;
102
103         temp = getpwnam(name);
104         
105         if (!temp) {
106 #if 0
107                 if (errno == ENOMEM) {
108                         /* what now? */
109                 }
110 #endif
111                 return NULL;
112         }
113
114         return alloc_copy_passwd(temp);
115 }
116
117 struct passwd *getpwuid_alloc(uid_t uid) 
118 {
119         struct passwd *temp;
120
121         temp = getpwuid(uid);
122         
123         if (!temp) {
124 #if 0
125                 if (errno == ENOMEM) {
126                         /* what now? */
127                 }
128 #endif
129                 return NULL;
130         }
131
132         return alloc_copy_passwd(temp);
133 }