smbnetfs  0.6.3
About: SMBNetFS is a Linux/FreeBSD filesystem that allow you to use samba/microsoft network in the same manner as the network neighborhood in Microsoft Windows.
  Fossies Dox: smbnetfs-0.6.3.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

auth.c
Go to the documentation of this file.
1 #include "config.h"
2 #include <pwd.h>
3 #include <time.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <pthread.h>
7 #include "list.h"
8 #include "common.h"
9 #include "auth-libsecret.h"
10 #include "auth.h"
11 
12 struct authitem{
13  char *name; // item name
14  time_t touch_time; // item touch time
15  struct authinfo *info;
16  struct{
17  int child_cnt; // number of subitem
18  int max_child_cnt; // maximum number of subitem
19  struct authitem **childs; // sorted list of subitems
20  };
21 };
22 
23 static char auth_login[64] = "guest";
24 static char *auth_fake_password = "********";
25 static struct authinfo authinfo_default = {{NULL, NULL}, 1, "", auth_login, ""};
27 static struct authitem authroot = {NULL, (time_t) 0, NULL, {0, 0, NULL}};
28 static pthread_mutex_t m_auth = PTHREAD_MUTEX_INITIALIZER;
29 
30 
32  strncpy(auth_login, name, sizeof(auth_login));
33  auth_login[sizeof(auth_login) - 1] = '\0';
34  DPRINTF(5, "login=%s\n", auth_login);
35 }
36 
37 static struct authinfo * authinfo_create_new(
38  const char *domain,
39  const char *user,
40  const char *password){
41 
42  size_t len;
43  struct authinfo *info;
44 
45  len = sizeof(struct authinfo) +
46  strlen(domain) + strlen(user) + strlen(password) + 3;
47  if ((info = malloc(len)) == NULL) return NULL;
48  memset(info, 0, len);
49 
50  info->domain = (char *) (info + 1);
51  info->user = info->domain + strlen(domain) + 1;
52  info->password = info->user + strlen(user) + 1;
53 
54  strcpy(info->domain, domain);
55  strcpy(info->user, user);
56  strcpy(info->password, password);
57 
58  return info;
59 }
60 
61 static inline void authinfo_delete(struct authinfo *info){
62  free(info);
63 }
64 
65 static inline int authinfo_compare(struct authinfo *info,
66  const char *domain,
67  const char *user,
68  const char *password){
69  return ((strcmp(info->domain, domain) == 0) &&
70  (strcmp(info->user, user) == 0) &&
71  (strcmp(info->password, password) == 0));
72 }
73 
75  const char *domain,
76  const char *user,
77  const char *password){
78 
79  struct authinfo *info;
80  LIST *elem;
81 
83  while(is_valid_list_elem(&authinfo_list, elem)){
84  info = list_entry(elem, struct authinfo, entries);
85  if (authinfo_compare(info, domain, user, password)) return info;
86  elem = elem->next;
87  }
88  return NULL;
89 }
90 
91 static struct authinfo * authinfo_store_list(
92  const char *domain,
93  const char *user,
94  const char *password){
95 
96  struct authinfo *info;
97 
98  DPRINTF(10, "domain=%s, user=%s, password=%s\n",
100 
102  if (info != NULL){
104  }else{
106  if (info == NULL) return NULL;
107  }
108 
109  info->ref_count++;
111  return info;
112 }
113 
114 static void authinfo_release(struct authinfo *info){
115  info->ref_count--;
116  if (info->ref_count == 0){
118  authinfo_delete(info);
119  }
120 }
121 
122 static struct authitem* authitem_create_item(const char *name){
123  struct authitem *item;
124 
125  item = malloc(sizeof(struct authitem) + strlen(name) + 1);
126  if (item == NULL) return NULL;
127 
128  memset(item, 0 , sizeof(struct authitem));
129  item->name = (char *) (item + 1);
130  strcpy(item->name, name);
131  item->touch_time = time(NULL);
132  return item;
133 }
134 
135 static inline void authitem_delete_item(struct authitem *item){
136  if (item->info != NULL) authinfo_release(item->info);
137  if (item->childs != NULL) free(item->childs);
138  free(item);
139 }
140 
141 static void authitem_delete_obsolete_items(struct authitem *item, time_t threshold){
142  int i;
143 
144  for(i = item->child_cnt - 1; i >= 0; i--){
145  authitem_delete_obsolete_items(item->childs[i], threshold);
146  if ((item->childs[i]->info == NULL) &&
147  (item->childs[i]->childs == NULL)){
148 
149  authitem_delete_item(item->childs[i]);
150  if (i != item->child_cnt - 1){
151  memmove(&item->childs[i],
152  &item->childs[i + 1],
153  (item->child_cnt - i - 1) * sizeof(struct authitem *));
154  }
155  item->child_cnt--;
156  }
157  }
158  if ((item->touch_time < threshold) && (item->info != NULL)){
159  authinfo_release(item->info);
160  item->info = NULL;
161  }
162  if ((item->child_cnt == 0) && (item->childs != NULL)){
163  free(item->childs);
164  item->childs = NULL;
165  item->max_child_cnt = 0;
166  }
167 }
168 
169 /*
170  * This function search for an item in specified authitem subitems,
171  * subitems MUST be sorted alphabetically, so we can bisect.
172  *
173  * return:
174  * a) item position, if item with specified name was found
175  * b) negative value -(pos+1), if item was not found,
176  * where 'pos' is the position to insert the new element
177  */
178 static int authitem_find_subitem(struct authitem *item, const char *name){
179  int first = 0, last = item->child_cnt - 1;
180 
181  while(first <= last){
182  int i = (first + last) >> 1;
183  int result = strcasecmp(item->childs[i]->name, name);
184 
185  if (result == 0) return i;
186  if (result < 0) first = i + 1;
187  else last = i - 1;
188  }
189  return -(first + 1);
190 }
191 
192 /*
193  * This function insert an element to specified authitem,
194  * insert position MUST be obtained with authitem_find_subitem().
195  *
196  * return:
197  * a) zero, if no errors
198  * b) (-1), if insertion failed
199  */
200 static int authitem_insert_subitem(struct authitem *item,
201  struct authitem *subitem, int pos){
202  if ((pos > item->child_cnt) || (pos < 0)) return -1;
203 
204  if (item->max_child_cnt == item->child_cnt){
205  struct authitem **new_childs;
206  int new_max_cnt;
207 
208  new_max_cnt = (item->max_child_cnt == 0) ?
209  64 : 2 * item->max_child_cnt;
210  new_childs = realloc(item->childs,
211  new_max_cnt * sizeof(struct authitem *));
212  if (new_childs == NULL) return -1;
213 
214  item->max_child_cnt = new_max_cnt;
215  item->childs = new_childs;
216  }
217 
218  if (pos < item->child_cnt){
219  memmove(&item->childs[pos + 1],
220  &item->childs[pos],
221  (item->child_cnt - pos) * sizeof(struct authitem *));
222  }
223  item->childs[pos] = subitem;
224  item->child_cnt++;
225  return 0;
226 }
227 
229  struct authitem *item,
230  const char *name){
231  int pos;
232  struct authitem *subitem;
233 
234  pos = authitem_find_subitem(item, name);
235  if (pos < 0){
236  /* create new subitem and add it to item */
237  subitem = authitem_create_item(name);
238  if (subitem == NULL) return NULL;
239  pos = -(pos + 1);
240  if (authitem_insert_subitem(item, subitem, pos) != 0){
241  authitem_delete_item(subitem);
242  return NULL;
243  }
244  }
245  return item->childs[pos];
246 }
247 
249  const char *domain,
250  const char *server,
251  const char *share,
252  int *suitability){
253 
254  int pos;
255  struct authitem *item;
256  struct authinfo *info;
257 
258  DPRINTF(10, "domain=%s, server=%s, share=%s\n", domain, server, share);
259 
260  if ((server == NULL) || (*server == '\0')) return NULL;
261  if (domain == NULL) domain = "";
262  if (share == NULL) share = "";
263 
264  item = &authroot;
265  info = &authinfo_default;
266  *suitability = AUTH_FALLBACK;
267  pthread_mutex_lock(&m_auth);
268  if (item->info != NULL){
269  info = item->info;
270  *suitability = AUTH_MATCH_DEFAULT;
271  }
272  if (*domain != '\0'){
273  pos = authitem_find_subitem(item, domain);
274  if ((pos >= 0) && (item->childs[pos]->info != NULL)){
275  info = item->childs[pos]->info;
276  *suitability = AUTH_MATCH_DOMAIN_COMPAT;
277  }
278  }
279 
280  if ((pos = authitem_find_subitem(item, server)) < 0) goto end;
281  item = item->childs[pos];
282  if (item->info != NULL){
283  info = item->info;
284  *suitability = AUTH_MATCH_SERVER;
285  }
286 
287  if (*share == '\0') goto end;
288  if ((pos = authitem_find_subitem(item, share)) < 0) goto end;
289  item = item->childs[pos];
290  if (item->info != NULL){
291  info = item->info;
292  *suitability = AUTH_MATCH_RESOURCE;
293  }
294 
295  end:
296  info->ref_count++;
297  pthread_mutex_unlock(&m_auth);
298  DPRINTF(10, "domain=%s, user=%s, password=%s, suitability=%d\n",
299  info->domain, info->user, auth_fake_password, *suitability);
300  return info;
301 }
302 
303 void auth_release_authinfo(struct authinfo *info){
304  pthread_mutex_lock(&m_auth);
305  authinfo_release(info);
306  pthread_mutex_unlock(&m_auth);
307 }
308 
309 int auth_store_auth_data(const char *server,
310  const char *share,
311  const char *domain,
312  const char *user,
313  const char *password){
314 
315  int result;
316  struct authinfo *info;
317  struct authitem *item;
318 
319  DPRINTF(10, "smb://%s/%s, domain=%s, user=%s, password=%s\n",
320  server, share, domain, user, auth_fake_password);
321 
322  if ((user == NULL) || (*user == '\0')) return -1;
323  if (server == NULL) server = "";
324  if (share == NULL) share = "";
325  if (domain == NULL) domain = "";
326  if (password == NULL) password = "";
327  if ((*server == '\0') && (*share != '\0')) return -1;
328 
329  result = -1;
330  item = &authroot;
331  pthread_mutex_lock(&m_auth);
332  if (*server == '\0') goto update_info;
333  if ((item = authitem_get_subitem(item, server)) == NULL) goto error;
334 
335  if (*share == '\0') goto update_info;
336  if ((item = authitem_get_subitem(item, share)) == NULL) goto error;
337 
338  update_info:
339  if ((item->info == NULL) ||
340  ! authinfo_compare(item->info, domain, user, password)){
341 
342  info = authinfo_store_list(domain, user, password);
343  if (info == NULL) goto error;
344  if (item->info != NULL) authinfo_release(item->info);
345  item->info = info;
346  }
347  item->touch_time = time(NULL);
348  result = 0;
349 
350  error:
351  pthread_mutex_unlock(&m_auth);
352  return result;
353 }
354 
355 void auth_delete_obsolete(time_t threshold){
356  pthread_mutex_lock(&m_auth);
358  pthread_mutex_unlock(&m_auth);
359 }
#define AUTH_MATCH_DEFAULT
Definition: auth-libsecret.h:5
#define AUTH_FALLBACK
Definition: auth-libsecret.h:4
#define AUTH_MATCH_SERVER
Definition: auth-libsecret.h:8
#define AUTH_MATCH_RESOURCE
Definition: auth-libsecret.h:9
#define AUTH_MATCH_DOMAIN_COMPAT
Definition: auth-libsecret.h:6
static int authitem_insert_subitem(struct authitem *item, struct authitem *subitem, int pos)
Definition: auth.c:200
static struct authinfo authinfo_default
Definition: auth.c:25
void auth_delete_obsolete(time_t threshold)
Definition: auth.c:355
static char auth_login[64]
Definition: auth.c:23
static struct authinfo * authinfo_find_in_list(const char *domain, const char *user, const char *password)
Definition: auth.c:74
static void authinfo_delete(struct authinfo *info)
Definition: auth.c:61
static char * auth_fake_password
Definition: auth.c:24
static struct authitem * authitem_get_subitem(struct authitem *item, const char *name)
Definition: auth.c:228
static void authitem_delete_obsolete_items(struct authitem *item, time_t threshold)
Definition: auth.c:141
static LIST authinfo_list
Definition: auth.c:26
void auth_set_default_login_name(const char *name)
Definition: auth.c:31
static struct authitem * authitem_create_item(const char *name)
Definition: auth.c:122
struct authinfo * auth_get_authinfo(const char *domain, const char *server, const char *share, int *suitability)
Definition: auth.c:248
static struct authinfo * authinfo_store_list(const char *domain, const char *user, const char *password)
Definition: auth.c:91
static struct authitem authroot
Definition: auth.c:27
static int authitem_find_subitem(struct authitem *item, const char *name)
Definition: auth.c:178
static pthread_mutex_t m_auth
Definition: auth.c:28
static int authinfo_compare(struct authinfo *info, const char *domain, const char *user, const char *password)
Definition: auth.c:65
static void authinfo_release(struct authinfo *info)
Definition: auth.c:114
int auth_store_auth_data(const char *server, const char *share, const char *domain, const char *user, const char *password)
Definition: auth.c:309
static void authitem_delete_item(struct authitem *item)
Definition: auth.c:135
static struct authinfo * authinfo_create_new(const char *domain, const char *user, const char *password)
Definition: auth.c:37
void auth_release_authinfo(struct authinfo *info)
Definition: auth.c:303
#define DPRINTF(level, fmt, args...)
Definition: common.h:47
static int is_valid_list_elem(LIST *list, LIST *elem)
Definition: list.h:88
static LIST * first_list_elem(LIST *list)
Definition: list.h:16
static void add_to_list_back(LIST *list, LIST *elem)
Definition: list.h:34
#define list_entry(ptr, type, member)
Definition: list.h:11
#define STATIC_LIST_INITIALIZER(list)
Definition: list.h:14
static void remove_from_list(LIST *list, LIST *elem)
Definition: list.h:77
Definition: list.h:6
struct __LIST * next
Definition: list.h:7
Definition: auth.h:6
char * domain
Definition: auth.h:9
char * user
Definition: auth.h:10
char * password
Definition: auth.h:11
int ref_count
Definition: auth.h:8
LIST entries
Definition: auth.h:7
Definition: auth.c:12
struct authitem ** childs
Definition: auth.c:19
time_t touch_time
Definition: auth.c:14
int child_cnt
Definition: auth.c:17
char * name
Definition: auth.c:13
int max_child_cnt
Definition: auth.c:18
struct authinfo * info
Definition: auth.c:15