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