diff options
Diffstat (limited to 'source3/winbindd/winbindd_group.c')
-rw-r--r-- | source3/winbindd/winbindd_group.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c new file mode 100644 index 0000000..a90889e --- /dev/null +++ b/source3/winbindd/winbindd_group.c @@ -0,0 +1,154 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon for ntdom nss module + + Copyright (C) Tim Potter 2000 + Copyright (C) Jeremy Allison 2001. + Copyright (C) Gerald (Jerry) Carter 2003. + Copyright (C) Volker Lendecke 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "winbindd.h" +#include "lib/dbwrap/dbwrap.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND + +/* Fill a grent structure from various other information */ + +bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr, + const char *dom_name, const char *gr_name, gid_t unix_gid) +{ + const char *full_group_name; + char *mapped_name = NULL; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + nt_status = normalize_name_map(mem_ctx, dom_name, gr_name, + &mapped_name); + + D_DEBUG("Filling domain '%s' and group '%s'.\n", dom_name, gr_name); + /* Basic whitespace replacement */ + if (NT_STATUS_IS_OK(nt_status)) { + full_group_name = fill_domain_username_talloc(mem_ctx, dom_name, + mapped_name, true); + } + /* Mapped to an aliase */ + else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) { + full_group_name = mapped_name; + } + /* no change */ + else { + full_group_name = fill_domain_username_talloc(mem_ctx, dom_name, + gr_name, True ); + } + + if (full_group_name == NULL) { + D_DEBUG("Returning false, since there is no full group name.\n"); + return false; + } + + gr->gr_gid = unix_gid; + + /* Group name and password */ + + strlcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name)); + strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd)); + + D_DEBUG("Returning true. Full group name is '%s'.\n", gr_name); + return True; +} + +struct getgr_countmem { + int num; + size_t len; +}; + +static int getgr_calc_memberlen(struct db_record *rec, void *private_data) +{ + struct getgr_countmem *buf = private_data; + TDB_DATA data = dbwrap_record_get_value(rec); + size_t len; + + buf->num += 1; + + len = buf->len + data.dsize; + if (len < buf->len) { + return 0; + } + buf->len = len; + return 0; +} + +struct getgr_stringmem { + size_t ofs; + char *buf; +}; + +static int getgr_unparse_members(struct db_record *rec, void *private_data) +{ + struct getgr_stringmem *buf = private_data; + TDB_DATA data = dbwrap_record_get_value(rec); + int len; + + len = data.dsize-1; + + memcpy(buf->buf + buf->ofs, data.dptr, len); + buf->ofs += len; + buf->buf[buf->ofs] = ','; + buf->ofs += 1; + return 0; +} + +NTSTATUS winbindd_print_groupmembers(struct db_context *members, + TALLOC_CTX *mem_ctx, + int *num_members, char **result) +{ + struct getgr_countmem c; + struct getgr_stringmem m; + int count; + NTSTATUS status; + + c.num = 0; + c.len = 0; + + status = dbwrap_traverse(members, getgr_calc_memberlen, &c, &count); + if (!NT_STATUS_IS_OK(status)) { + DBG_NOTICE("dbwrap_traverse failed: %s\n", nt_errstr(status)); + return status; + } + + m.ofs = 0; + m.buf = talloc_array(mem_ctx, char, c.len); + if (m.buf == NULL) { + D_WARNING("talloc failed\n"); + return NT_STATUS_NO_MEMORY; + } + + status = dbwrap_traverse(members, getgr_unparse_members, &m, &count); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(m.buf); + DBG_NOTICE("dbwrap_traverse failed: %s\n", nt_errstr(status)); + return status; + } + m.buf[c.len-1] = '\0'; + + *num_members = c.num; + *result = m.buf; + D_DEBUG("Returning %d member(s).\n", *num_members); + return NT_STATUS_OK; +} |