support IDMAP_BOTH over the winbind pipe
Michael Adam
obnox at samba.org
Tue Sep 20 03:05:23 MDT 2011
Hi Andrew,
the mail slipped my attention originally.
Thanks for pinging me.
I will look over the patches tomorrow or so.
Cheers - Michael
Andrew Bartlett wrote:
> Michael,
>
> Tridge and I wrote up some patches to add support for IDMAP_BOTH (a SID
> mapped to both a UID and a GID) to the winbindd pipe.
>
> We did this as we experiment with ways to more closely combine the file
> server and the AD DC, in the hope that we can eventually switch file
> servers.
>
> Attached are the patches. I wondered if you might have time to look
> over them, and see if you think they are OK.
>
> Thanks,
>
> Andrew Bartlett
> --
> Andrew Bartlett http://samba.org/~abartlet/
> Authentication Developer, Samba Team http://samba.org
> >From aaeebaca6e15ee34140705090fb6baaebaec98c8 Mon Sep 17 00:00:00 2001
> From: Andrew Tridgell <tridge at samba.org>
> Date: Tue, 26 Jul 2011 11:05:38 +1000
> Subject: [PATCH 1/2] nsswitch: added support for WBC_ID_TYPE_BOTH
>
> the Samba4 winbindd allows for a single SID to map to both a user and
> group id. This is use to support files with the owner_sid set to a
> group
>
> Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
> ---
> nsswitch/libwbclient/wbc_idmap.c | 4 ++++
> nsswitch/libwbclient/wbclient.h | 3 ++-
> nsswitch/wbinfo.c | 3 +++
> 3 files changed, 9 insertions(+), 1 deletions(-)
>
> diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
> index 5325dbe..04e7d02 100644
> --- a/nsswitch/libwbclient/wbc_idmap.c
> +++ b/nsswitch/libwbclient/wbc_idmap.c
> @@ -370,6 +370,10 @@ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
> id->type = WBC_ID_TYPE_GID;
> id->id.gid = strtoul(p+1, &q, 10);
> break;
> + case 'B':
> + id->type = WBC_ID_TYPE_BOTH;
> + id->id.uid = strtoul(p+1, &q, 10);
> + break;
> default:
> id->type = WBC_ID_TYPE_NOT_SPECIFIED;
> q = strchr(p, '\n');
> diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
> index c5f3b77..809e00a 100644
> --- a/nsswitch/libwbclient/wbclient.h
> +++ b/nsswitch/libwbclient/wbclient.h
> @@ -796,7 +796,8 @@ wbcErr wbcQueryGidToSid(gid_t gid,
> enum wbcIdType {
> WBC_ID_TYPE_NOT_SPECIFIED,
> WBC_ID_TYPE_UID,
> - WBC_ID_TYPE_GID
> + WBC_ID_TYPE_GID,
> + WBC_ID_TYPE_BOTH
> };
>
> union wbcUnixIdContainer {
> diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
> index 30e23b6..6459b8e 100644
> --- a/nsswitch/wbinfo.c
> +++ b/nsswitch/wbinfo.c
> @@ -1018,6 +1018,9 @@ static bool wbinfo_sids_to_unix_ids(const char *arg)
> case WBC_ID_TYPE_GID:
> d_printf("%s -> gid %d\n", sidstr, unix_ids[i].id.gid);
> break;
> + case WBC_ID_TYPE_BOTH:
> + d_printf("%s -> uid/gid %d\n", sidstr, unix_ids[i].id.uid);
> + break;
> default:
> d_printf("%s -> unmapped\n", sidstr);
> break;
> --
> 1.7.6
>
> >From 8da0216b1edfa8c93d8723333997cf731587927e Mon Sep 17 00:00:00 2001
> From: Andrew Tridgell <tridge at samba.org>
> Date: Tue, 26 Jul 2011 11:07:12 +1000
> Subject: [PATCH 2/2] s3-winbindd: add support for idmap type WBC_ID_TYPE_BOTH
>
> this allows the s3 code to understand and cache responses from the s4
> winbindd which may include a single SID mapped to both a uid and a gid
>
> Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
> ---
> source3/auth/auth_util.c | 3 +-
> source3/lib/idmap_cache.c | 57 +++++++++++++++++++++++++++++-
> source3/lib/idmap_cache.h | 2 +
> source3/smbd/msg_idmap.c | 27 ++++++++++++++
> source3/winbindd/winbindd_sids_to_xids.c | 6 +++
> 5 files changed, 93 insertions(+), 2 deletions(-)
>
> diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
> index f41809d..11b220e 100644
> --- a/source3/auth/auth_util.c
> +++ b/source3/auth/auth_util.c
> @@ -608,7 +608,8 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
>
> for (i=1; i<t->num_sids; i++) {
>
> - if (ids[i].type != WBC_ID_TYPE_GID) {
> + if (ids[i].type != WBC_ID_TYPE_GID &&
> + ids[i].type != WBC_ID_TYPE_BOTH) {
> DEBUG(10, ("Could not convert SID %s to gid, "
> "ignoring it\n",
> sid_string_dbg(&t->sids[i])));
> diff --git a/source3/lib/idmap_cache.c b/source3/lib/idmap_cache.c
> index 6783215..413029c 100644
> --- a/source3/lib/idmap_cache.c
> +++ b/source3/lib/idmap_cache.c
> @@ -261,7 +261,54 @@ void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
> }
> }
>
> +
> +/**
> + * Store a mapping in the idmap cache
> + * @param[in] sid the sid to map
> + * @param[in] uid/gid the uid/gid to map
> + *
> + * If both parameters are valid values, then a positive mapping in both
> + * directions is stored. If "is_null_sid(sid)" is true, then this will be a
> + * negative mapping of gid, we want to cache that for this id we could not
> + * find anything. Likewise if "id==-1", then we want to cache that we did not
> + * find a mapping for the sid passed here.
> + */
> +
> +void idmap_cache_set_sid2both(const struct dom_sid *sid, uid_t id)
> +{
> + time_t now = time(NULL);
> + time_t timeout;
> + fstring sidstr, key, value;
> +
> + if (!is_null_sid(sid)) {
> + fstr_sprintf(key, "IDMAP/SID2BOTH/%s",
> + sid_to_fstring(sidstr, sid));
> + fstr_sprintf(value, "%d", (int)id);
> + timeout = (id == -1)
> + ? lp_idmap_negative_cache_time()
> + : lp_idmap_cache_time();
> + gencache_set(key, value, now + timeout);
> + }
> + if (id != -1) {
> + fstr_sprintf(key, "IDMAP/BOTH2SID/%d", (int)id);
> + if (is_null_sid(sid)) {
> + /* negative id mapping */
> + fstrcpy(value, "-");
> + timeout = lp_idmap_negative_cache_time();
> + }
> + else {
> + sid_to_fstring(value, sid);
> + timeout = lp_idmap_cache_time();
> + }
> + gencache_set(key, value, now + timeout);
> + }
> +}
> +
> +
> static char* key_xid2sid_str(TALLOC_CTX* mem_ctx, char t, const char* id) {
> + if (t == 'B') {
> + return talloc_asprintf(mem_ctx, "IDMAP/BOTH2SID/%s", id);
> + }
> return talloc_asprintf(mem_ctx, "IDMAP/%cID2SID/%s", t, id);
> }
>
> @@ -272,6 +319,9 @@ static char* key_xid2sid(TALLOC_CTX* mem_ctx, char t, int id) {
> }
>
> static char* key_sid2xid_str(TALLOC_CTX* mem_ctx, char t, const char* sid) {
> + if (t == 'B') {
> + return talloc_asprintf(mem_ctx, "IDMAP/SID2BOTH/%s", sid);
> + }
> return talloc_asprintf(mem_ctx, "IDMAP/SID2%cID/%s", t, sid);
> }
>
> @@ -328,6 +378,10 @@ bool idmap_cache_del_gid(gid_t gid) {
> return idmap_cache_del_xid('G', gid);
> }
>
> +bool idmap_cache_del_both(uid_t id) {
> + return idmap_cache_del_xid('B', id);
> +}
> +
> static bool idmap_cache_del_sid2xid(TALLOC_CTX* mem_ctx, char t, const char* sid)
> {
> const char* sid_key = key_sid2xid_str(mem_ctx, t, sid);
> @@ -367,7 +421,8 @@ bool idmap_cache_del_sid(const struct dom_sid *sid)
> bool ret = true;
>
> if (!idmap_cache_del_sid2xid(mem_ctx, 'U', sid_str) &&
> - !idmap_cache_del_sid2xid(mem_ctx, 'G', sid_str))
> + !idmap_cache_del_sid2xid(mem_ctx, 'G', sid_str) &&
> + !idmap_cache_del_sid2xid(mem_ctx, 'B', sid_str))
> {
> DEBUG(3, ("no entry: %s\n", key_xid2sid_str(mem_ctx, '?', sid_str)));
> ret = false;
> diff --git a/source3/lib/idmap_cache.h b/source3/lib/idmap_cache.h
> index 1a62dba..4c87139 100644
> --- a/source3/lib/idmap_cache.h
> +++ b/source3/lib/idmap_cache.h
> @@ -31,9 +31,11 @@ bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid,
> bool *expired);
> bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired);
> void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid);
> +void idmap_cache_set_sid2both(const struct dom_sid *sid, uid_t id);
>
> bool idmap_cache_del_uid(uid_t uid);
> bool idmap_cache_del_gid(gid_t gid);
> +bool idmap_cache_del_both(uid_t uid);
> bool idmap_cache_del_sid(const struct dom_sid *sid);
>
> #endif /* _LIB_IDMAP_CACHE_H_ */
> diff --git a/source3/smbd/msg_idmap.c b/source3/smbd/msg_idmap.c
> index dbd151d..2ef2a47 100644
> --- a/source3/smbd/msg_idmap.c
> +++ b/source3/smbd/msg_idmap.c
> @@ -28,6 +28,33 @@
> #include "messages.h"
> #include "lib/id_cache.h"
>
> +static bool parse_id(const char* str, struct id_cache_ref *id)
> +{
> + struct dom_sid sid;
> + unsigned long ul;
> + char c, trash;
> +
> + if (sscanf(str, "%cID %lu%c", &c, &ul, &trash) == 2) {
> + switch(c) {
> + case 'G':
> + id->id.gid = ul;
> + id->type = GID;
> + return true;
> + case 'U':
> + id->id.uid = ul;
> + id->type = UID;
> + return true;
> + default:
> + break;
> + }
> + } else if (string_to_sid(&sid, str)) {
> + id->id.sid = sid;
> + id->type = SID;
> + return true;
> + }
> + return false;
> +}
> +
> static bool uid_in_use(const struct user_struct *user, uid_t uid)
> {
> while (user) {
> diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c
> index d08064f..b416e3a 100644
> --- a/source3/winbindd/winbindd_sids_to_xids.c
> +++ b/source3/winbindd/winbindd_sids_to_xids.c
> @@ -284,6 +284,12 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
> &state->non_cached[num_non_cached],
> unix_id);
> break;
> + case WBC_ID_TYPE_BOTH:
> + type = 'B';
> + idmap_cache_set_sid2both(
> + &state->non_cached[num_non_cached],
> + unix_id);
> + break;
> default:
> found = false;
> }
> --
> 1.7.6
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 206 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20110920/33e22bc8/attachment.pgp>
More information about the samba-technical
mailing list