2 * Samba Unix/Linux SMB client library
4 * Copyright (C) Gregor Beck 2011
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.
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.
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/>.
21 * @brief Notify smbd about idmap changes
23 * @author Gregor Beck <gb@sernet.de>
31 #include "../libcli/security/dom_sid.h"
32 #include "../librpc/gen_ndr/messaging.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "idmap_cache.h"
42 enum {UID
, GID
, SID
} type
;
45 static bool parse_id(const char* str
, struct id
* id
)
51 if (sscanf(str
, "%cID %lu%c", &c
, &ul
, &trash
) == 2) {
64 } else if (string_to_sid(&sid
, str
)) {
72 static bool uid_in_use(const struct user_struct
* user
, uid_t uid
)
75 if (user
->session_info
&& (user
->session_info
->utok
.uid
== uid
)) {
83 static bool gid_in_use(const struct user_struct
* user
, gid_t gid
)
86 if (user
->session_info
!= NULL
) {
88 struct security_unix_token utok
= user
->session_info
->utok
;
89 if (utok
.gid
== gid
) {
92 for(i
=0; i
<utok
.ngroups
; i
++) {
93 if (utok
.groups
[i
] == gid
) {
103 static bool sid_in_use(const struct user_struct
* user
, const struct dom_sid
* psid
)
107 if (sid_to_gid(psid
, &gid
)) {
108 return gid_in_use(user
, gid
);
109 } else if (sid_to_uid(psid
, &uid
)) {
110 return uid_in_use(user
, uid
);
116 static bool id_in_use(const struct user_struct
* user
, const struct id
* id
)
120 return uid_in_use(user
, id
->id
.uid
);
122 return gid_in_use(user
, id
->id
.gid
);
124 return sid_in_use(user
, &id
->id
.sid
);
131 static void delete_from_cache(const struct id
* id
)
135 delete_uid_cache(id
->id
.uid
);
136 idmap_cache_del_uid(id
->id
.uid
);
139 delete_gid_cache(id
->id
.gid
);
140 idmap_cache_del_gid(id
->id
.gid
);
143 delete_sid_cache(&id
->id
.sid
);
144 idmap_cache_del_sid(&id
->id
.sid
);
152 static void message_idmap_flush(struct messaging_context
*msg_ctx
,
155 struct server_id server_id
,
158 const char* msg
= data
? (const char*)data
->data
: NULL
;
160 if ((msg
== NULL
) || (msg
[0] == '\0')) {
163 } else if (strncmp(msg
, "GID", 3)) {
165 } else if (strncmp(msg
, "UID", 3)) {
168 DEBUG(0, ("Invalid argument: %s\n", msg
));
173 static void message_idmap_delete(struct messaging_context
*msg_ctx
,
176 struct server_id server_id
,
179 const char* msg
= (data
&& data
->data
) ? (const char*)data
->data
: "<NULL>";
180 bool do_kill
= (msg_type
== MSG_IDMAP_KILL
);
181 struct user_struct
* validated_users
= smbd_server_conn
->smb1
.sessions
.validated_users
;
184 if (!parse_id(msg
, &id
)) {
185 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
189 if( do_kill
&& id_in_use(validated_users
, &id
) ) {
190 exit_server_cleanly(msg
);
192 delete_from_cache(&id
);
196 void msg_idmap_register_msgs(struct messaging_context
*ctx
)
198 messaging_register(ctx
, NULL
, MSG_IDMAP_FLUSH
, message_idmap_flush
);
199 messaging_register(ctx
, NULL
, MSG_IDMAP_DELETE
, message_idmap_delete
);
200 messaging_register(ctx
, NULL
, MSG_IDMAP_KILL
, message_idmap_delete
);