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>
29 #include "smbd/smbd.h"
31 #include "../libcli/security/dom_sid.h"
32 #include "idmap_cache.h"
33 #include "passdb/lookup_sid.h"
43 enum {UID
, GID
, SID
} type
;
46 static bool parse_id(const char* str
, struct id
* id
)
52 if (sscanf(str
, "%cID %lu%c", &c
, &ul
, &trash
) == 2) {
65 } else if (string_to_sid(&sid
, str
)) {
73 static bool uid_in_use(const struct user_struct
* user
, uid_t uid
)
76 if (user
->session_info
&& (user
->session_info
->utok
.uid
== uid
)) {
84 static bool gid_in_use(const struct user_struct
* user
, gid_t gid
)
87 if (user
->session_info
!= NULL
) {
89 struct security_unix_token utok
= user
->session_info
->utok
;
90 if (utok
.gid
== gid
) {
93 for(i
=0; i
<utok
.ngroups
; i
++) {
94 if (utok
.groups
[i
] == gid
) {
104 static bool sid_in_use(const struct user_struct
* user
, const struct dom_sid
* psid
)
108 if (sid_to_gid(psid
, &gid
)) {
109 return gid_in_use(user
, gid
);
110 } else if (sid_to_uid(psid
, &uid
)) {
111 return uid_in_use(user
, uid
);
117 static bool id_in_use(const struct user_struct
* user
, const struct id
* id
)
121 return uid_in_use(user
, id
->id
.uid
);
123 return gid_in_use(user
, id
->id
.gid
);
125 return sid_in_use(user
, &id
->id
.sid
);
132 static void delete_from_cache(const struct id
* id
)
136 delete_uid_cache(id
->id
.uid
);
137 idmap_cache_del_uid(id
->id
.uid
);
140 delete_gid_cache(id
->id
.gid
);
141 idmap_cache_del_gid(id
->id
.gid
);
144 delete_sid_cache(&id
->id
.sid
);
145 idmap_cache_del_sid(&id
->id
.sid
);
153 static void message_idmap_flush(struct messaging_context
*msg_ctx
,
156 struct server_id server_id
,
159 const char* msg
= data
? (const char*)data
->data
: NULL
;
161 if ((msg
== NULL
) || (msg
[0] == '\0')) {
164 } else if (strncmp(msg
, "GID", 3)) {
166 } else if (strncmp(msg
, "UID", 3)) {
169 DEBUG(0, ("Invalid argument: %s\n", msg
));
174 static void message_idmap_delete(struct messaging_context
*msg_ctx
,
177 struct server_id server_id
,
180 const char* msg
= (data
&& data
->data
) ? (const char*)data
->data
: "<NULL>";
181 bool do_kill
= (msg_type
== MSG_IDMAP_KILL
);
182 struct user_struct
* validated_users
= smbd_server_conn
->smb1
.sessions
.validated_users
;
185 if (!parse_id(msg
, &id
)) {
186 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
190 if( do_kill
&& id_in_use(validated_users
, &id
) ) {
191 exit_server_cleanly(msg
);
193 delete_from_cache(&id
);
197 void msg_idmap_register_msgs(struct messaging_context
*ctx
)
199 messaging_register(ctx
, NULL
, MSG_IDMAP_FLUSH
, message_idmap_flush
);
200 messaging_register(ctx
, NULL
, MSG_IDMAP_DELETE
, message_idmap_delete
);
201 messaging_register(ctx
, NULL
, MSG_IDMAP_KILL
, message_idmap_delete
);