getncchanges: fix highest_usn off by one calculation in get_nc_changes_add_links()
[sfrench/samba-autobuild/.git] / source4 / rpc_server / unixinfo / dcesrv_unixinfo.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the unixinfo pipe
5
6    Copyright (C) Volker Lendecke 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpc_server/dcerpc_server.h"
24 #include "librpc/gen_ndr/ndr_unixinfo.h"
25 #include "libcli/wbclient/wbclient.h"
26 #include "system/passwd.h"
27
28 static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call,
29                                   TALLOC_CTX *mem_ctx,
30                                   struct unixinfo_SidToUid *r)
31 {
32         NTSTATUS status;
33         struct id_map *ids;
34
35         DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n"));
36
37         ids = talloc(mem_ctx, struct id_map);
38         NT_STATUS_HAVE_NO_MEMORY(ids);
39
40         ids->sid = &r->in.sid;
41         ids->status = ID_UNKNOWN;
42         ZERO_STRUCT(ids->xid);
43         status = wbc_sids_to_xids(ids, 1);
44         NT_STATUS_NOT_OK_RETURN(status);
45
46         if (ids->xid.type == ID_TYPE_BOTH ||
47             ids->xid.type == ID_TYPE_UID) {
48                 *r->out.uid = ids->xid.id;
49                 return NT_STATUS_OK;
50         } else {
51                 return NT_STATUS_INVALID_SID;
52         }
53 }
54
55 static NTSTATUS dcesrv_unixinfo_UidToSid(struct dcesrv_call_state *dce_call,
56                                   TALLOC_CTX *mem_ctx,
57                                   struct unixinfo_UidToSid *r)
58 {
59         struct id_map *ids;
60         uint32_t uid;
61         NTSTATUS status;
62
63         DEBUG(5, ("dcesrv_unixinfo_UidToSid called\n"));
64
65         uid = r->in.uid;        /* This cuts uid to 32 bit */
66         if ((uint64_t)uid != r->in.uid) {
67                 DEBUG(10, ("uid out of range\n"));
68                 return NT_STATUS_INVALID_PARAMETER;
69         }
70
71         ids = talloc(mem_ctx, struct id_map);
72         NT_STATUS_HAVE_NO_MEMORY(ids);
73
74         ids->sid = NULL;
75         ids->status = ID_UNKNOWN;
76
77         ids->xid.id = uid;
78         ids->xid.type = ID_TYPE_UID;
79
80         status = wbc_xids_to_sids(ids, 1);
81         NT_STATUS_NOT_OK_RETURN(status);
82
83         r->out.sid = ids->sid;
84         return NT_STATUS_OK;
85 }
86
87 static NTSTATUS dcesrv_unixinfo_SidToGid(struct dcesrv_call_state *dce_call,
88                                   TALLOC_CTX *mem_ctx,
89                                   struct unixinfo_SidToGid *r)
90 {
91         NTSTATUS status;
92         struct id_map *ids;
93
94         DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n"));
95
96         ids = talloc(mem_ctx, struct id_map);
97         NT_STATUS_HAVE_NO_MEMORY(ids);
98
99         ids->sid = &r->in.sid;
100         ids->status = ID_UNKNOWN;
101         ZERO_STRUCT(ids->xid);
102         status = wbc_sids_to_xids(ids, 1);
103         NT_STATUS_NOT_OK_RETURN(status);
104
105         if (ids->xid.type == ID_TYPE_BOTH ||
106             ids->xid.type == ID_TYPE_GID) {
107                 *r->out.gid = ids->xid.id;
108                 return NT_STATUS_OK;
109         } else {
110                 return NT_STATUS_INVALID_SID;
111         }
112 }
113
114 static NTSTATUS dcesrv_unixinfo_GidToSid(struct dcesrv_call_state *dce_call,
115                                   TALLOC_CTX *mem_ctx,
116                                   struct unixinfo_GidToSid *r)
117 {
118         struct id_map *ids;
119         uint32_t gid;
120         NTSTATUS status;
121
122         DEBUG(5, ("dcesrv_unixinfo_GidToSid called\n"));
123
124         gid = r->in.gid;        /* This cuts gid to 32 bit */
125         if ((uint64_t)gid != r->in.gid) {
126                 DEBUG(10, ("gid out of range\n"));
127                 return NT_STATUS_INVALID_PARAMETER;
128         }
129
130         ids = talloc(mem_ctx, struct id_map);
131         NT_STATUS_HAVE_NO_MEMORY(ids);
132
133         ids->sid = NULL;
134         ids->status = ID_UNKNOWN;
135
136         ids->xid.id = gid;
137         ids->xid.type = ID_TYPE_GID;
138
139         status = wbc_xids_to_sids(ids, 1);
140         NT_STATUS_NOT_OK_RETURN(status);
141
142         r->out.sid = ids->sid;
143         return NT_STATUS_OK;
144 }
145
146 static NTSTATUS dcesrv_unixinfo_GetPWUid(struct dcesrv_call_state *dce_call,
147                                   TALLOC_CTX *mem_ctx,
148                                   struct unixinfo_GetPWUid *r)
149 {
150         unsigned int i;
151
152         *r->out.count = 0;
153
154         r->out.infos = talloc_zero_array(mem_ctx, struct unixinfo_GetPWUidInfo,
155                                          *r->in.count);
156         NT_STATUS_HAVE_NO_MEMORY(r->out.infos);
157         *r->out.count = *r->in.count;
158
159         for (i=0; i < *r->in.count; i++) {
160                 uid_t uid;
161                 struct passwd *pwd;
162
163                 uid = r->in.uids[i];
164                 pwd = getpwuid(uid);
165                 if (pwd == NULL) {
166                         DEBUG(10, ("uid %d not found\n", uid));
167                         r->out.infos[i].homedir = "";
168                         r->out.infos[i].shell = "";
169                         r->out.infos[i].status = NT_STATUS_NO_SUCH_USER;
170                         continue;
171                 }
172
173                 r->out.infos[i].homedir = talloc_strdup(mem_ctx, pwd->pw_dir);
174                 r->out.infos[i].shell = talloc_strdup(mem_ctx, pwd->pw_shell);
175
176                 if ((r->out.infos[i].homedir == NULL) ||
177                     (r->out.infos[i].shell == NULL)) {
178                         r->out.infos[i].homedir = "";
179                         r->out.infos[i].shell = "";
180                         r->out.infos[i].status = NT_STATUS_NO_MEMORY;
181                         continue;
182                 }
183
184                 r->out.infos[i].status = NT_STATUS_OK;
185         }
186
187         return NT_STATUS_OK;
188 }
189
190 /* include the generated boilerplate */
191 #include "librpc/gen_ndr/ndr_unixinfo_s.c"