s3-winbindd: use fill_domain_username_talloc() in winbind.
[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 #include "lib/dbwrap/dbwrap.h"
28
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_WINBIND
31
32 /* Fill a grent structure from various other information */
33
34 bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr,
35                 const char *dom_name, const char *gr_name, gid_t unix_gid)
36 {
37         const char *full_group_name;
38         char *mapped_name = NULL;
39         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
40
41         nt_status = normalize_name_map(mem_ctx, dom_name, gr_name,
42                                        &mapped_name);
43
44         /* Basic whitespace replacement */
45         if (NT_STATUS_IS_OK(nt_status)) {
46                 full_group_name = fill_domain_username_talloc(mem_ctx, dom_name,
47                                      mapped_name, true);
48         }
49         /* Mapped to an aliase */
50         else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
51                 full_group_name = mapped_name;
52         }
53         /* no change */
54         else {
55                 full_group_name = fill_domain_username_talloc(mem_ctx, dom_name,
56                                       gr_name, True );
57         }
58
59         if (full_group_name == NULL) {
60                 return false;
61         }
62
63         gr->gr_gid = unix_gid;
64
65         /* Group name and password */
66
67         strlcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name));
68         strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd));
69
70         return True;
71 }
72
73 struct getgr_countmem {
74         int num;
75         size_t len;
76 };
77
78 static int getgr_calc_memberlen(struct db_record *rec, void *private_data)
79 {
80         struct getgr_countmem *buf = private_data;
81         TDB_DATA data = dbwrap_record_get_value(rec);
82         size_t len;
83
84         buf->num += 1;
85
86         len = buf->len + data.dsize;
87         if (len < buf->len) {
88                 return 0;
89         }
90         buf->len = len;
91         return 0;
92 }
93
94 struct getgr_stringmem {
95         size_t ofs;
96         char *buf;
97 };
98
99 static int getgr_unparse_members(struct db_record *rec, void *private_data)
100 {
101         struct getgr_stringmem *buf = private_data;
102         TDB_DATA data = dbwrap_record_get_value(rec);
103         int len;
104
105         len = data.dsize-1;
106
107         memcpy(buf->buf + buf->ofs, data.dptr, 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 db_context *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 count;
121         NTSTATUS status;
122
123         c.num = 0;
124         c.len = 0;
125
126         status = dbwrap_traverse(members, getgr_calc_memberlen, &c, &count);
127         if (!NT_STATUS_IS_OK(status)) {
128                 DBG_NOTICE("dbwrap_traverse failed: %s\n", nt_errstr(status));
129                 return status;
130         }
131
132         m.ofs = 0;
133         m.buf = talloc_array(mem_ctx, char, c.len);
134         if (m.buf == NULL) {
135                 DEBUG(5, ("talloc failed\n"));
136                 return NT_STATUS_NO_MEMORY;
137         }
138
139         status = dbwrap_traverse(members, getgr_unparse_members, &m, &count);
140         if (!NT_STATUS_IS_OK(status)) {
141                 TALLOC_FREE(m.buf);
142                 DBG_NOTICE("dbwrap_traverse failed: %s\n", nt_errstr(status));
143                 return status;
144         }
145         m.buf[c.len-1] = '\0';
146
147         *num_members = c.num;
148         *result = m.buf;
149         return NT_STATUS_OK;
150 }