1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2007-2011 Kern Sibbald
5
6 This program is Free Software; you can redistribute it and/or
7 modify it under the terms of version three of the GNU Affero General Public
8 License as published by the Free Software Foundation, which is
9 listed in the file LICENSE.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Affero General Public License for more details.
15
16 You should have received a copy of the GNU Affero General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20 */
21 /*
22 * Written by Kern Sibbald, July 2007 to replace idcache.c
23 *
24 * Program to convert uid and gid into names, and cache the results
25 * for preformance reasons.
26 */
27
28 #include "include/bareos.h"
29 #include "lib/edit.h"
30 #include "lib/dlist.h"
31
32 #ifndef WIN32
33 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
34 #endif
35
36 struct guitem {
37 dlink link;
38 char* name;
39 union {
40 uid_t uid;
41 gid_t gid;
42 };
43 };
44
45
new_guid_list()46 guid_list* new_guid_list()
47 {
48 guid_list* list;
49 guitem* item = NULL;
50 list = (guid_list*)malloc(sizeof(guid_list));
51 list->uid_list = new dlist(item, &item->link);
52 list->gid_list = new dlist(item, &item->link);
53 return list;
54 }
55
FreeGuidList(guid_list * list)56 void FreeGuidList(guid_list* list)
57 {
58 guitem* item;
59 foreach_dlist (item, list->uid_list) {
60 free(item->name);
61 }
62 foreach_dlist (item, list->gid_list) {
63 free(item->name);
64 }
65 delete list->uid_list;
66 delete list->gid_list;
67 free(list);
68 }
69
UidCompare(void * item1,void * item2)70 static int UidCompare(void* item1, void* item2)
71 {
72 guitem* i1 = (guitem*)item1;
73 guitem* i2 = (guitem*)item2;
74 if (i1->uid < i2->uid) {
75 return -1;
76 } else if (i1->uid > i2->uid) {
77 return 1;
78 } else {
79 return 0;
80 }
81 }
82
GidCompare(void * item1,void * item2)83 static int GidCompare(void* item1, void* item2)
84 {
85 guitem* i1 = (guitem*)item1;
86 guitem* i2 = (guitem*)item2;
87 if (i1->gid < i2->gid) {
88 return -1;
89 } else if (i1->gid > i2->gid) {
90 return 1;
91 } else {
92 return 0;
93 }
94 }
95
96
GetUidname(uid_t uid,guitem * item)97 static void GetUidname(uid_t uid, guitem* item)
98 {
99 #ifndef HAVE_WIN32
100 struct passwd* pwbuf;
101 P(mutex);
102 pwbuf = getpwuid(uid);
103 if (pwbuf != NULL && !bstrcmp(pwbuf->pw_name, "????????")) {
104 item->name = strdup(pwbuf->pw_name);
105 }
106 V(mutex);
107 #endif
108 }
109
GetGidname(gid_t gid,guitem * item)110 static void GetGidname(gid_t gid, guitem* item)
111 {
112 #ifndef HAVE_WIN32
113 struct group* grbuf;
114 P(mutex);
115 grbuf = getgrgid(gid);
116 if (grbuf != NULL && !bstrcmp(grbuf->gr_name, "????????")) {
117 item->name = strdup(grbuf->gr_name);
118 }
119 V(mutex);
120 #endif
121 }
122
123
uid_to_name(uid_t uid,char * name,int maxlen)124 char* guid_list::uid_to_name(uid_t uid, char* name, int maxlen)
125 {
126 guitem sitem, *item, *fitem;
127 sitem.uid = uid;
128 char buf[50];
129
130 item = (guitem*)uid_list->binary_search(&sitem, UidCompare);
131 Dmsg2(900, "uid=%d item=%p\n", uid, item);
132 if (!item) {
133 item = (guitem*)malloc(sizeof(guitem));
134 item->uid = uid;
135 item->name = NULL;
136 GetUidname(uid, item);
137 if (!item->name) {
138 item->name = strdup(edit_int64(uid, buf));
139 Dmsg2(900, "set uid=%d name=%s\n", uid, item->name);
140 }
141 fitem = (guitem*)uid_list->binary_insert(item, UidCompare);
142 if (fitem != item) { /* item already there this shouldn't happen */
143 free(item->name);
144 free(item);
145 item = fitem;
146 }
147 }
148 bstrncpy(name, item->name, maxlen);
149 return name;
150 }
151
gid_to_name(gid_t gid,char * name,int maxlen)152 char* guid_list::gid_to_name(gid_t gid, char* name, int maxlen)
153 {
154 guitem sitem, *item, *fitem;
155 sitem.gid = gid;
156 char buf[50];
157
158 item = (guitem*)gid_list->binary_search(&sitem, GidCompare);
159 if (!item) {
160 item = (guitem*)malloc(sizeof(guitem));
161 item->gid = gid;
162 item->name = NULL;
163 GetGidname(gid, item);
164 if (!item->name) { item->name = strdup(edit_int64(gid, buf)); }
165 fitem = (guitem*)gid_list->binary_insert(item, GidCompare);
166 if (fitem != item) { /* item already there this shouldn't happen */
167 free(item->name);
168 free(item);
169 item = fitem;
170 }
171 }
172
173 bstrncpy(name, item->name, maxlen);
174 return name;
175 }
176