• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/rpc_server/unixinfo/
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
28static NTSTATUS dcerpc_unixinfo_bind(struct dcesrv_call_state *dce_call,
29				     const struct dcesrv_interface *iface)
30{
31	struct wbc_context *wbc_ctx;
32
33	wbc_ctx = wbc_init(dce_call->context, dce_call->msg_ctx,
34			   dce_call->event_ctx);
35	NT_STATUS_HAVE_NO_MEMORY(wbc_ctx);
36
37	dce_call->context->private_data = wbc_ctx;
38
39	return NT_STATUS_OK;
40}
41
42#define DCESRV_INTERFACE_UNIXINFO_BIND dcerpc_unixinfo_bind
43
44static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call,
45				  TALLOC_CTX *mem_ctx,
46				  struct unixinfo_SidToUid *r)
47{
48	NTSTATUS status;
49	struct wbc_context *wbc_ctx = talloc_get_type_abort(
50						dce_call->context->private_data,
51						struct wbc_context);
52	struct id_mapping *ids;
53	struct composite_context *ctx;
54
55	DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n"));
56
57	ids = talloc(mem_ctx, struct  id_mapping);
58	NT_STATUS_HAVE_NO_MEMORY(ids);
59
60	ids->sid = &r->in.sid;
61	ids->status = NT_STATUS_NONE_MAPPED;
62	ids->unixid = NULL;
63	ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids);
64	NT_STATUS_HAVE_NO_MEMORY(ctx);
65
66	status = wbc_sids_to_xids_recv(ctx, &ids);
67	NT_STATUS_NOT_OK_RETURN(status);
68
69	if (ids->unixid->type == ID_TYPE_BOTH ||
70	    ids->unixid->type == ID_TYPE_UID) {
71		*r->out.uid = ids->unixid->id;
72		return NT_STATUS_OK;
73	} else {
74		return NT_STATUS_INVALID_SID;
75	}
76}
77
78static NTSTATUS dcesrv_unixinfo_UidToSid(struct dcesrv_call_state *dce_call,
79				  TALLOC_CTX *mem_ctx,
80				  struct unixinfo_UidToSid *r)
81{
82	struct wbc_context *wbc_ctx = talloc_get_type_abort(
83						dce_call->context->private_data,
84						struct wbc_context);
85	struct id_mapping *ids;
86	struct composite_context *ctx;
87	uint32_t uid;
88	NTSTATUS status;
89
90	DEBUG(5, ("dcesrv_unixinfo_UidToSid called\n"));
91
92	uid = r->in.uid; 	/* This cuts uid to 32 bit */
93	if ((uint64_t)uid != r->in.uid) {
94		DEBUG(10, ("uid out of range\n"));
95		return NT_STATUS_INVALID_PARAMETER;
96	}
97
98	ids = talloc(mem_ctx, struct id_mapping);
99	NT_STATUS_HAVE_NO_MEMORY(ids);
100
101	ids->sid = NULL;
102	ids->status = NT_STATUS_NONE_MAPPED;
103	ids->unixid = talloc(ids, struct unixid);
104	NT_STATUS_HAVE_NO_MEMORY(ids->unixid);
105
106	ids->unixid->id = uid;
107	ids->unixid->type = ID_TYPE_UID;
108
109	ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids);
110	NT_STATUS_HAVE_NO_MEMORY(ctx);
111
112	status = wbc_xids_to_sids_recv(ctx, &ids);
113	NT_STATUS_NOT_OK_RETURN(status);
114
115	r->out.sid = ids->sid;
116	return NT_STATUS_OK;
117}
118
119static NTSTATUS dcesrv_unixinfo_SidToGid(struct dcesrv_call_state *dce_call,
120				  TALLOC_CTX *mem_ctx,
121				  struct unixinfo_SidToGid *r)
122{
123	NTSTATUS status;
124	struct wbc_context *wbc_ctx = talloc_get_type_abort(
125						dce_call->context->private_data,
126						struct wbc_context);
127	struct id_mapping *ids;
128	struct composite_context *ctx;
129
130	DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n"));
131
132	ids = talloc(mem_ctx, struct  id_mapping);
133	NT_STATUS_HAVE_NO_MEMORY(ids);
134
135	ids->sid = &r->in.sid;
136	ids->status = NT_STATUS_NONE_MAPPED;
137	ids->unixid = NULL;
138	ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids);
139	NT_STATUS_HAVE_NO_MEMORY(ctx);
140
141	status = wbc_sids_to_xids_recv(ctx, &ids);
142	NT_STATUS_NOT_OK_RETURN(status);
143
144	if (ids->unixid->type == ID_TYPE_BOTH ||
145	    ids->unixid->type == ID_TYPE_GID) {
146		*r->out.gid = ids->unixid->id;
147		return NT_STATUS_OK;
148	} else {
149		return NT_STATUS_INVALID_SID;
150	}
151}
152
153static NTSTATUS dcesrv_unixinfo_GidToSid(struct dcesrv_call_state *dce_call,
154				  TALLOC_CTX *mem_ctx,
155				  struct unixinfo_GidToSid *r)
156{
157	struct wbc_context *wbc_ctx = talloc_get_type_abort(
158						dce_call->context->private_data,
159						struct wbc_context);
160	struct id_mapping *ids;
161	struct composite_context *ctx;
162	uint32_t gid;
163	NTSTATUS status;
164
165	DEBUG(5, ("dcesrv_unixinfo_GidToSid called\n"));
166
167	gid = r->in.gid; 	/* This cuts gid to 32 bit */
168	if ((uint64_t)gid != r->in.gid) {
169		DEBUG(10, ("gid out of range\n"));
170		return NT_STATUS_INVALID_PARAMETER;
171	}
172
173	ids = talloc(mem_ctx, struct id_mapping);
174	NT_STATUS_HAVE_NO_MEMORY(ids);
175
176	ids->sid = NULL;
177	ids->status = NT_STATUS_NONE_MAPPED;
178	ids->unixid = talloc(ids, struct unixid);
179	NT_STATUS_HAVE_NO_MEMORY(ids->unixid);
180
181	ids->unixid->id = gid;
182	ids->unixid->type = ID_TYPE_GID;
183
184	ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids);
185	NT_STATUS_HAVE_NO_MEMORY(ctx);
186
187	status = wbc_xids_to_sids_recv(ctx, &ids);
188	NT_STATUS_NOT_OK_RETURN(status);
189
190	r->out.sid = ids->sid;
191	return NT_STATUS_OK;
192}
193
194static NTSTATUS dcesrv_unixinfo_GetPWUid(struct dcesrv_call_state *dce_call,
195				  TALLOC_CTX *mem_ctx,
196				  struct unixinfo_GetPWUid *r)
197{
198	int i;
199
200	*r->out.count = 0;
201
202	r->out.infos = talloc_zero_array(mem_ctx, struct unixinfo_GetPWUidInfo,
203					 *r->in.count);
204	NT_STATUS_HAVE_NO_MEMORY(r->out.infos);
205	*r->out.count = *r->in.count;
206
207	for (i=0; i < *r->in.count; i++) {
208		uid_t uid;
209		struct passwd *pwd;
210
211		uid = r->in.uids[i];
212		pwd = getpwuid(uid);
213		if (pwd == NULL) {
214			DEBUG(10, ("uid %d not found\n", uid));
215			r->out.infos[i].homedir = "";
216			r->out.infos[i].shell = "";
217			r->out.infos[i].status = NT_STATUS_NO_SUCH_USER;
218			continue;
219		}
220
221		r->out.infos[i].homedir = talloc_strdup(mem_ctx, pwd->pw_dir);
222		r->out.infos[i].shell = talloc_strdup(mem_ctx, pwd->pw_shell);
223
224		if ((r->out.infos[i].homedir == NULL) ||
225		    (r->out.infos[i].shell == NULL)) {
226			r->out.infos[i].homedir = "";
227			r->out.infos[i].shell = "";
228			r->out.infos[i].status = NT_STATUS_NO_MEMORY;
229			continue;
230		}
231
232		r->out.infos[i].status = NT_STATUS_OK;
233	}
234
235	return NT_STATUS_OK;
236}
237
238/* include the generated boilerplate */
239#include "librpc/gen_ndr/ndr_unixinfo_s.c"
240