2 Unix SMB/Netbios implementation.
4 Pipe SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1997,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
7 Copyright (C) Paul Ashton 1997.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 This file handles reply_ calls on named pipes that the server
25 makes to handle specific protocols
33 extern int DEBUGLEVEL
;
37 /***************************************************************************
39 ***************************************************************************/
40 static int lsa_reply_open_policy(char *q
, char *base
)
45 /* set up the LSA QUERY INFO response */
46 bzero(&(r_o
.pol
.data
), POL_HND_SIZE
);
47 for (i
= 4; i
< POL_HND_SIZE
; i
++)
53 /* store the response in the SMB stream */
54 q
= lsa_io_r_open_pol(False
, &r_o
, q
, base
, 4, 0);
56 /* return length of SMB data stored */
57 return PTR_DIFF(q
, base
);
60 /***************************************************************************
62 ***************************************************************************/
63 static void make_dom_query(DOM_QUERY
*d_q
, char *dom_name
, char *dom_sid
)
65 int domlen
= strlen(dom_name
);
67 d_q
->uni_dom_max_len
= domlen
* 2;
68 d_q
->uni_dom_str_len
= domlen
* 2;
70 d_q
->buffer_dom_name
= 4; /* domain buffer pointer */
71 d_q
->buffer_dom_sid
= 2; /* domain sid pointer */
73 /* this string is supposed to be character short */
74 make_unistr2(&(d_q
->uni_domain_name
), dom_name
, domlen
);
76 make_dom_sid(&(d_q
->dom_sid
), dom_sid
);
79 /***************************************************************************
81 ***************************************************************************/
82 static int lsa_reply_query_info(LSA_Q_QUERY_INFO
*q_q
, char *q
, char *base
,
83 char *dom_name
, char *dom_sid
)
87 /* set up the LSA QUERY INFO response */
89 r_q
.undoc_buffer
= 0x22000000; /* bizarre */
90 r_q
.info_class
= q_q
->info_class
;
92 make_dom_query(&r_q
.dom
.id5
, dom_name
, dom_sid
);
96 /* store the response in the SMB stream */
97 q
= lsa_io_r_query(False
, &r_q
, q
, base
, 4, 0);
99 /* return length of SMB data stored */
100 return PTR_DIFF(q
, base
);
103 /***************************************************************************
106 pretty much hard-coded choice of "other" sids, unfortunately...
108 ***************************************************************************/
109 static void make_dom_ref(DOM_R_REF
*ref
,
110 char *dom_name
, char *dom_sid
,
111 char *other_sid1
, char *other_sid2
, char *other_sid3
)
113 int len_dom_name
= strlen(dom_name
);
114 int len_other_sid1
= strlen(other_sid1
);
115 int len_other_sid2
= strlen(other_sid2
);
116 int len_other_sid3
= strlen(other_sid3
);
118 ref
->undoc_buffer
= 1;
119 ref
->num_ref_doms_1
= 4;
120 ref
->buffer_dom_name
= 1;
121 ref
->max_entries
= 32;
122 ref
->num_ref_doms_2
= 4;
124 make_uni_hdr2(&(ref
->hdr_dom_name
), len_dom_name
, len_dom_name
, 0);
125 make_uni_hdr2(&(ref
->hdr_ref_dom
[0]), len_other_sid1
, len_other_sid1
, 0);
126 make_uni_hdr2(&(ref
->hdr_ref_dom
[1]), len_other_sid2
, len_other_sid2
, 0);
127 make_uni_hdr2(&(ref
->hdr_ref_dom
[2]), len_other_sid3
, len_other_sid3
, 0);
129 if (dom_name
!= NULL
)
131 make_unistr(&(ref
->uni_dom_name
), dom_name
);
134 make_dom_sid(&(ref
->ref_dom
[0]), dom_sid
);
135 make_dom_sid(&(ref
->ref_dom
[1]), other_sid1
);
136 make_dom_sid(&(ref
->ref_dom
[2]), other_sid2
);
137 make_dom_sid(&(ref
->ref_dom
[3]), other_sid3
);
140 /***************************************************************************
141 make_reply_lookup_rids
142 ***************************************************************************/
143 static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS
*r_l
,
144 int num_entries
, uint32 dom_rids
[MAX_LOOKUP_SIDS
],
145 char *dom_name
, char *dom_sid
,
146 char *other_sid1
, char *other_sid2
, char *other_sid3
)
150 make_dom_ref(&(r_l
->dom_ref
), dom_name
, dom_sid
,
151 other_sid1
, other_sid2
, other_sid3
);
153 r_l
->num_entries
= num_entries
;
154 r_l
->undoc_buffer
= 1;
155 r_l
->num_entries2
= num_entries
;
157 for (i
= 0; i
< num_entries
; i
++)
159 make_dom_rid2(&(r_l
->dom_rid
[i
]), dom_rids
[i
]);
162 r_l
->num_entries3
= num_entries
;
165 /***************************************************************************
166 make_reply_lookup_sids
167 ***************************************************************************/
168 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
169 int num_entries
, fstring dom_sids
[MAX_LOOKUP_SIDS
],
170 char *dom_name
, char *dom_sid
,
171 char *other_sid1
, char *other_sid2
, char *other_sid3
)
175 make_dom_ref(&(r_l
->dom_ref
), dom_name
, dom_sid
,
176 other_sid1
, other_sid2
, other_sid3
);
178 r_l
->num_entries
= num_entries
;
179 r_l
->undoc_buffer
= 1;
180 r_l
->num_entries2
= num_entries
;
182 for (i
= 0; i
< num_entries
; i
++)
184 make_dom_sid2(&(r_l
->dom_sid
[i
]), dom_sids
[i
]);
187 r_l
->num_entries3
= num_entries
;
190 /***************************************************************************
191 lsa_reply_lookup_sids
192 ***************************************************************************/
193 static int lsa_reply_lookup_sids(char *q
, char *base
,
194 int num_entries
, fstring dom_sids
[MAX_LOOKUP_SIDS
],
195 char *dom_name
, char *dom_sid
,
196 char *other_sid1
, char *other_sid2
, char *other_sid3
)
198 LSA_R_LOOKUP_SIDS r_l
;
200 /* set up the LSA Lookup SIDs response */
201 make_reply_lookup_sids(&r_l
, num_entries
, dom_sids
,
202 dom_name
, dom_sid
, other_sid1
, other_sid2
, other_sid3
);
205 /* store the response in the SMB stream */
206 q
= lsa_io_r_lookup_sids(False
, &r_l
, q
, base
, 4, 0);
208 /* return length of SMB data stored */
209 return PTR_DIFF(q
, base
);
212 /***************************************************************************
213 lsa_reply_lookup_rids
214 ***************************************************************************/
215 static int lsa_reply_lookup_rids(char *q
, char *base
,
216 int num_entries
, uint32 dom_rids
[MAX_LOOKUP_SIDS
],
217 char *dom_name
, char *dom_sid
,
218 char *other_sid1
, char *other_sid2
, char *other_sid3
)
220 LSA_R_LOOKUP_RIDS r_l
;
222 /* set up the LSA Lookup RIDs response */
223 make_reply_lookup_rids(&r_l
, num_entries
, dom_rids
,
224 dom_name
, dom_sid
, other_sid1
, other_sid2
, other_sid3
);
227 /* store the response in the SMB stream */
228 q
= lsa_io_r_lookup_rids(False
, &r_l
, q
, base
, 4, 0);
230 /* return length of SMB data stored */
231 return PTR_DIFF(q
, base
);
234 /***************************************************************************
236 ***************************************************************************/
237 static void api_lsa_open_policy( char *param
, char *data
,
238 char **rdata
, int *rdata_len
)
242 /* grab the server, object attributes and desired access flag...*/
243 lsa_io_q_open_pol(True
, &q_o
, data
+ 0x18, data
, 4, 0);
245 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
247 /* return a 20 byte policy handle */
248 *rdata_len
= lsa_reply_open_policy(*rdata
+ 0x18, *rdata
);
251 /***************************************************************************
253 ***************************************************************************/
254 static void api_lsa_query_info( char *param
, char *data
,
255 char **rdata
, int *rdata_len
)
257 LSA_Q_QUERY_INFO q_i
;
261 /* grab the info class and policy handle */
262 lsa_io_q_query(True
, &q_i
, data
+ 0x18, data
, 4, 0);
264 pstrcpy(dom_name
, lp_workgroup());
265 pstrcpy(dom_sid
, lp_domain_sid());
267 /* construct reply. return status is always 0x0 */
268 *rdata_len
= lsa_reply_query_info(&q_i
, *rdata
+ 0x18, *rdata
,
272 /***************************************************************************
274 ***************************************************************************/
275 static void api_lsa_lookup_sids( char *param
, char *data
,
276 char **rdata
, int *rdata_len
)
279 LSA_Q_LOOKUP_SIDS q_l
;
282 fstring dom_sids
[MAX_LOOKUP_SIDS
];
284 /* grab the info class and policy handle */
285 lsa_io_q_lookup_sids(True
, &q_l
, data
+ 0x18, data
, 4, 0);
287 pstrcpy(dom_name
, lp_workgroup());
288 pstrcpy(dom_sid
, lp_domain_sid());
290 /* convert received SIDs to strings, so we can do them. */
291 for (i
= 0; i
< q_l
.num_entries
; i
++)
293 fstrcpy(dom_sids
[i
], dom_sid_to_string(&(q_l
.dom_sids
[i
])));
296 /* construct reply. return status is always 0x0 */
297 *rdata_len
= lsa_reply_lookup_sids(*rdata
+ 0x18, *rdata
,
298 q_l
.num_entries
, dom_sids
, /* text-converted SIDs */
299 dom_name
, dom_sid
, /* domain name, domain SID */
300 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
303 /***************************************************************************
305 ***************************************************************************/
306 static void api_lsa_lookup_names( char *param
, char *data
,
307 char **rdata
, int *rdata_len
)
310 LSA_Q_LOOKUP_RIDS q_l
;
313 uint32 dom_rids
[MAX_LOOKUP_SIDS
];
316 /* grab the info class and policy handle */
317 lsa_io_q_lookup_rids(True
, &q_l
, data
+ 0x18, data
, 4, 0);
319 pstrcpy(dom_name
, lp_workgroup());
320 pstrcpy(dom_sid
, lp_domain_sid());
322 /* convert received RIDs to strings, so we can do them. */
323 for (i
= 0; i
< q_l
.num_entries
; i
++)
325 char *user_name
= unistr2(q_l
.lookup_name
[i
].str
.buffer
);
326 if (!name_to_rid(user_name
, &dom_rids
[i
], &dummy_g_rid
))
328 /* WHOOPS! we should really do something about this... */
333 /* construct reply. return status is always 0x0 */
334 *rdata_len
= lsa_reply_lookup_rids(*rdata
+ 0x18, *rdata
,
335 q_l
.num_entries
, dom_rids
, /* text-converted SIDs */
336 dom_name
, dom_sid
, /* domain name, domain SID */
337 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
340 /***************************************************************************
342 ***************************************************************************/
343 BOOL
api_ntLsarpcTNP(int cnum
,int uid
, char *param
,char *data
,
344 int mdrcnt
,int mprcnt
,
345 char **rdata
,char **rparam
,
346 int *rdata_len
,int *rparam_len
)
352 DEBUG(2,("api_ntLsarpcTNP: NULL data received\n"));
356 smb_io_rpc_hdr_rr(True
, &hdr
, data
, data
, 4, 0);
358 DEBUG(4,("lsarpc TransactNamedPipe op %x\n",hdr
.opnum
));
364 DEBUG(3,("LSA_OPENPOLICY\n"));
365 api_lsa_open_policy(param
, data
, rdata
, rdata_len
);
366 create_rpc_reply(hdr
.hdr
.call_id
, *rdata
, *rdata_len
);
370 case LSA_QUERYINFOPOLICY
:
372 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
374 api_lsa_query_info(param
, data
, rdata
, rdata_len
);
375 create_rpc_reply(hdr
.hdr
.call_id
, *rdata
, *rdata_len
);
379 case LSA_ENUMTRUSTDOM
:
381 char *q
= *rdata
+ 0x18;
383 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
385 initrpcreply(data
, *rdata
);
387 SIVAL(q
, 0, 0); /* enumeration context */
388 SIVAL(q
, 0, 4); /* entries read */
389 SIVAL(q
, 0, 8); /* trust information */
393 endrpcreply(data
, *rdata
, q
-*rdata
, 0x8000001a, rdata_len
);
402 DEBUG(3,("LSA_CLOSE\n"));
404 initrpcreply(data
, *rdata
);
408 SIVAL(q
, 0, 0); q
+= 4;
409 SIVAL(q
, 0, 0); q
+= 4;
410 SIVAL(q
, 0, 0); q
+= 4;
411 SIVAL(q
, 0, 0); q
+= 4;
412 SIVAL(q
, 0, 0); q
+= 4;
414 endrpcreply(data
, *rdata
, q
-*rdata
, 0, rdata_len
);
421 char *q
= *rdata
+ 0x18;
422 DEBUG(3,("LSA_OPENSECRET\n"));
424 initrpcreply(data
, *rdata
);
434 endrpcreply(data
, *rdata
, q
-*rdata
, 0xc000034, rdata_len
);
441 DEBUG(3,("LSA_OPENSECRET\n"));
442 api_lsa_lookup_sids(param
, data
, rdata
, rdata_len
);
443 create_rpc_reply(hdr
.hdr
.call_id
, *rdata
, *rdata_len
);
447 case LSA_LOOKUPNAMES
:
449 DEBUG(3,("LSA_LOOKUPNAMES\n"));
450 api_lsa_lookup_names(param
, data
, rdata
, rdata_len
);
451 create_rpc_reply(hdr
.hdr
.call_id
, *rdata
, *rdata_len
);
457 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", hdr
.opnum
));
464 #endif /* NTDOMAIN */