vfs: Fix parentheses in SMB_VFS_NEXT_DURABLE_COOKIE
[mat/samba.git] / source3 / winbindd / winbindd_group.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon for ntdom nss module
5
6    Copyright (C) Tim Potter 2000
7    Copyright (C) Jeremy Allison 2001.
8    Copyright (C) Gerald (Jerry) Carter 2003.
9    Copyright (C) Volker Lendecke 2005
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "winbindd.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
30
31 /* Fill a grent structure from various other information */
32
33 bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr,
34                 const char *dom_name, const char *gr_name, gid_t unix_gid)
35 {
36         fstring full_group_name;
37         char *mapped_name = NULL;
38         struct winbindd_domain *domain;
39         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
40
41         domain = find_domain_from_name_noinit(dom_name);
42         if (domain == NULL) {
43                 DEBUG(0, ("Failed to find domain '%s'. "
44                           "Check connection to trusted domains!\n",
45                           dom_name));
46                 return false;
47         }
48
49         nt_status = normalize_name_map(mem_ctx, domain, gr_name,
50                                        &mapped_name);
51
52         /* Basic whitespace replacement */
53         if (NT_STATUS_IS_OK(nt_status)) {
54                 fill_domain_username(full_group_name, dom_name,
55                                      mapped_name, true);
56         }
57         /* Mapped to an aliase */
58         else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
59                 fstrcpy(full_group_name, mapped_name);
60         }
61         /* no change */
62         else {
63                 fill_domain_username( full_group_name, dom_name,
64                                       gr_name, True );
65         }
66
67         gr->gr_gid = unix_gid;
68
69         /* Group name and password */
70
71         strlcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name));
72         strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd));
73
74         return True;
75 }
76
77 struct getgr_countmem {
78         int num;
79         size_t len;
80 };
81
82 static int getgr_calc_memberlen(DATA_BLOB key, void *data, void *priv)
83 {
84         struct wbint_Principal *m = talloc_get_type_abort(
85                 data, struct wbint_Principal);
86         struct getgr_countmem *buf = (struct getgr_countmem *)priv;
87
88         buf->num += 1;
89         buf->len += strlen(m->name) + 1;
90         return 0;
91 }
92
93 struct getgr_stringmem {
94         size_t ofs;
95         char *buf;
96 };
97
98 static int getgr_unparse_members(DATA_BLOB key, void *data, void *priv)
99 {
100         struct wbint_Principal *m = talloc_get_type_abort(
101                 data, struct wbint_Principal);
102         struct getgr_stringmem *buf = (struct getgr_stringmem *)priv;
103         int len;
104
105         len = strlen(m->name);
106
107         memcpy(buf->buf + buf->ofs, m->name, len);
108         buf->ofs += len;
109         buf->buf[buf->ofs] = ',';
110         buf->ofs += 1;
111         return 0;
112 }
113
114 NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members,
115                                      TALLOC_CTX *mem_ctx,
116                                      int *num_members, char **result)
117 {
118         struct getgr_countmem c;
119         struct getgr_stringmem m;
120         int res;
121
122         c.num = 0;
123         c.len = 0;
124
125         res = talloc_dict_traverse(members, getgr_calc_memberlen, &c);
126         if (res == -1) {
127                 DEBUG(5, ("talloc_dict_traverse failed\n"));
128                 return NT_STATUS_INTERNAL_ERROR;
129         }
130
131         m.ofs = 0;
132         m.buf = talloc_array(mem_ctx, char, c.len);
133         if (m.buf == NULL) {
134                 DEBUG(5, ("talloc failed\n"));
135                 return NT_STATUS_NO_MEMORY;
136         }
137
138         res = talloc_dict_traverse(members, getgr_unparse_members, &m);
139         if (res == -1) {
140                 DEBUG(5, ("talloc_dict_traverse failed\n"));
141                 TALLOC_FREE(m.buf);
142                 return NT_STATUS_INTERNAL_ERROR;
143         }
144         m.buf[c.len-1] = '\0';
145
146         *num_members = c.num;
147         *result = m.buf;
148         return NT_STATUS_OK;
149 }