Line data Source code
1 : /*
2 : * Samba Unix/Linux SMB client library
3 : *
4 : * Copyright (C) Gregor Beck 2011
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : /**
21 : * @brief Notify smbd about idmap changes
22 : * @file msg_idmap.c
23 : * @author Gregor Beck <gb@sernet.de>
24 : * @date Feb 2011
25 : *
26 : */
27 :
28 : #include "includes.h"
29 : #include "messages.h"
30 : #include "lib/id_cache.h"
31 : #include "../lib/util/memcache.h"
32 : #include "idmap_cache.h"
33 : #include "../librpc/gen_ndr/ndr_security.h"
34 : #include "../libcli/security/dom_sid.h"
35 :
36 6 : bool id_cache_ref_parse(const char* str, struct id_cache_ref* id)
37 : {
38 : struct dom_sid sid;
39 : unsigned long ul;
40 : char c, trash;
41 :
42 6 : if (sscanf(str, "%cID %lu%c", &c, &ul, &trash) == 2) {
43 0 : switch(c) {
44 0 : case 'G':
45 0 : id->id.gid = ul;
46 0 : id->type = GID;
47 0 : return true;
48 0 : case 'U':
49 0 : id->id.uid = ul;
50 0 : id->type = UID;
51 0 : return true;
52 0 : default:
53 0 : break;
54 : }
55 6 : } else if (string_to_sid(&sid, str)) {
56 0 : id->id.sid = sid;
57 0 : id->type = SID;
58 0 : return true;
59 6 : } else if (strncmp(str, "USER ", 5) == 0) {
60 6 : id->id.name = str + 5;
61 6 : id->type = USERNAME;
62 6 : return true;
63 : }
64 0 : return false;
65 : }
66 :
67 6 : static bool delete_getpwnam_cache(const char *username)
68 : {
69 6 : DATA_BLOB name = data_blob_string_const_null(username);
70 6 : DEBUG(6, ("Delete passwd struct for %s from memcache\n",
71 : username));
72 6 : memcache_delete(NULL, GETPWNAM_CACHE, name);
73 6 : return true;
74 : }
75 :
76 6 : void id_cache_delete_from_cache(const struct id_cache_ref* id)
77 : {
78 6 : switch(id->type) {
79 0 : case UID:
80 0 : idmap_cache_del_uid(id->id.uid);
81 0 : break;
82 0 : case GID:
83 0 : idmap_cache_del_gid(id->id.gid);
84 0 : break;
85 0 : case SID:
86 0 : idmap_cache_del_sid(&id->id.sid);
87 0 : break;
88 6 : case USERNAME:
89 6 : delete_getpwnam_cache(id->id.name);
90 6 : break;
91 0 : default:
92 0 : break;
93 : }
94 6 : }
95 :
96 6 : void id_cache_delete_message(struct messaging_context *msg_ctx,
97 : void *private_data,
98 : uint32_t msg_type,
99 : struct server_id server_id,
100 : DATA_BLOB* data)
101 : {
102 6 : const char *msg = (data && data->data) ? (const char *)data->data : "<NULL>";
103 : struct id_cache_ref id;
104 :
105 6 : if (!id_cache_ref_parse(msg, &id)) {
106 0 : DEBUG(0, ("Invalid ?ID: %s\n", msg));
107 0 : return;
108 : }
109 :
110 6 : id_cache_delete_from_cache(&id);
111 : }
112 :
113 5270 : void id_cache_register_msgs(struct messaging_context *ctx)
114 : {
115 5270 : messaging_register(ctx, NULL, ID_CACHE_DELETE, id_cache_delete_message);
116 5270 : }
|