3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
9 * Copyright (C) Jeremy Allison 1998.
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 2 of the License, or
14 * (at your option) any later version.
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.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 extern int DEBUGLEVEL
;
31 extern DOM_SID global_sam_sid
;
32 extern fstring global_sam_name
;
33 extern DOM_SID global_member_sid
;
34 extern fstring global_myworkgroup
;
35 extern DOM_SID global_sid_S_1_1
;
36 extern DOM_SID global_sid_S_1_3
;
37 extern DOM_SID global_sid_S_1_5
;
39 /***************************************************************************
40 lsa_reply_open_policy2
41 ***************************************************************************/
42 static void lsa_reply_open_policy2(prs_struct
*rdata
)
49 /* set up the LSA QUERY INFO response */
51 for (i
= 4; i
< POL_HND_SIZE
; i
++)
57 /* store the response in the SMB stream */
58 lsa_io_r_open_pol2("", &r_o
, rdata
, 0);
61 /***************************************************************************
63 ***************************************************************************/
64 static void lsa_reply_open_policy(prs_struct
*rdata
)
71 /* set up the LSA QUERY INFO response */
73 for (i
= 4; i
< POL_HND_SIZE
; i
++)
79 /* store the response in the SMB stream */
80 lsa_io_r_open_pol("", &r_o
, rdata
, 0);
83 /***************************************************************************
85 ***************************************************************************/
86 static void make_dom_query(DOM_QUERY
*d_q
, char *dom_name
, DOM_SID
*dom_sid
)
89 int domlen
= strlen(dom_name
);
91 d_q
->uni_dom_max_len
= domlen
* 2;
92 d_q
->uni_dom_str_len
= domlen
* 2;
94 d_q
->buffer_dom_name
= domlen
!= 0 ? 1 : 0; /* domain buffer pointer */
95 d_q
->buffer_dom_sid
= dom_sid
!= NULL
? 1 : 0; /* domain sid pointer */
97 /* this string is supposed to be character short */
98 make_unistr2(&(d_q
->uni_domain_name
), dom_name
, domlen
);
100 sid_to_string(sid_str
, dom_sid
);
101 make_dom_sid2(&(d_q
->dom_sid
), dom_sid
);
104 /***************************************************************************
106 ***************************************************************************/
107 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM
*q_e
,
109 uint32 enum_context
, char *dom_name
, DOM_SID
*dom_sid
)
111 LSA_R_ENUM_TRUST_DOM r_e
;
115 /* set up the LSA QUERY INFO response */
116 make_r_enum_trust_dom(&r_e
, enum_context
, dom_name
, dom_sid
,
117 dom_name
!= NULL
? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM
);
119 /* store the response in the SMB stream */
120 lsa_io_r_enum_trust_dom("", &r_e
, rdata
, 0);
123 /***************************************************************************
125 ***************************************************************************/
126 static void lsa_reply_query_info(LSA_Q_QUERY_INFO
*q_q
, prs_struct
*rdata
,
127 char *dom_name
, DOM_SID
*dom_sid
)
129 LSA_R_QUERY_INFO r_q
;
133 /* set up the LSA QUERY INFO response */
135 r_q
.undoc_buffer
= 0x22000000; /* bizarre */
136 r_q
.info_class
= q_q
->info_class
;
138 make_dom_query(&r_q
.dom
.id5
, dom_name
, dom_sid
);
142 /* store the response in the SMB stream */
143 lsa_io_r_query("", &r_q
, rdata
, 0);
147 /***************************************************************************
148 make_dom_ref - adds a domain if it's not already in, returns the index
149 ***************************************************************************/
150 static int make_dom_ref(DOM_R_REF
*ref
, char *dom_name
, DOM_SID
*dom_sid
)
156 if (dom_name
!= NULL
)
158 for (num
= 0; num
< ref
->num_ref_doms_1
; num
++)
161 fstrcpy(domname
, unistr2_to_str(&ref
->ref_dom
[num
].uni_dom_name
));
162 if (strequal(domname
, dom_name
))
171 num
= ref
->num_ref_doms_1
;
174 if (num
>= MAX_REF_DOMAINS
)
176 /* index not found, already at maximum domain limit */
180 ref
->undoc_buffer
= 1;
181 ref
->num_ref_doms_1
= num
+1;
182 ref
->undoc_buffer2
= 1;
183 ref
->max_entries
= MAX_REF_DOMAINS
;
184 ref
->num_ref_doms_2
= num
+1;
186 len
= dom_name
!= NULL
? strlen(dom_name
) : 0;
188 make_uni_hdr(&(ref
->hdr_ref_dom
[num
].hdr_dom_name
), len
, len
, len
!= 0 ? 1 : 0);
189 ref
->hdr_ref_dom
[num
].ptr_dom_sid
= dom_sid
!= NULL
? 1 : 0;
191 make_unistr2 (&(ref
->ref_dom
[num
].uni_dom_name
), dom_name
, len
);
192 make_dom_sid2(&(ref
->ref_dom
[num
].ref_dom
), dom_sid
);
197 /***************************************************************************
198 make_reply_lookup_names
199 ***************************************************************************/
200 static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES
*r_l
,
202 DOM_SID dom_sids
[MAX_LOOKUP_SIDS
],
203 uint8 dom_types
[MAX_LOOKUP_SIDS
])
207 r_l
->num_entries
= 0;
208 r_l
->undoc_buffer
= 0;
209 r_l
->num_entries2
= 0;
212 r_l
->num_entries
= num_entries
;
213 r_l
->undoc_buffer
= 1;
214 r_l
->num_entries2
= num_entries
;
216 SMB_ASSERT_ARRAY(r_l
->dom_rid
, num_entries
);
218 for (i
= 0; i
< num_entries
; i
++)
220 DOM_SID sid
= dom_sids
[i
];
222 sid_split_rid(&sid
, &rid
);
223 make_dom_ref(&(r_l
->dom_ref
), dom_name
, dom_sid
);
224 make_dom_rid2(&(r_l
->dom_rid
[i
]), rid
, dom_types
[i
]);
227 r_l
->num_entries3
= num_entries
;
231 /***************************************************************************
233 ***************************************************************************/
234 static void make_lsa_trans_names(DOM_R_REF
*ref
,
235 LSA_TRANS_NAME_ENUM
*trn
,
236 int num_entries
, DOM_SID2 sid
[MAX_LOOKUP_SIDS
],
237 uint32
*mapped_count
)
243 SMB_ASSERT(num_entries
<= MAX_LOOKUP_SIDS
);
245 for (i
= 0; i
< num_entries
; i
++)
248 DOM_SID find_sid
= sid
[i
].sid
;
249 DOM_SID tmp_sid
= sid
[i
].sid
;
250 uint32 rid
= 0xffffffff;
254 uint8 sid_name_use
= 0;
256 memset(dom_name
, 0, sizeof(dom_name
));
257 memset(name
, 0, sizeof(name
));
259 if (map_domain_sid_to_name(&find_sid
, dom_name
))
261 sid_name_use
= SID_NAME_DOMAIN
;
262 dom_idx
= make_dom_ref(ref
, dom_name
, &find_sid
);
264 else if (sid_split_rid (&find_sid
, &rid
) &&
265 map_domain_sid_to_name(&find_sid
, dom_name
))
267 if (sid_equal(&find_sid
, &global_sam_sid
))
269 status
= lookup_sid(&tmp_sid
, name
, &sid_name_use
);
273 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
278 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
281 dom_idx
= make_dom_ref(ref
, dom_name
, &find_sid
);
289 snprintf(name
, sizeof(name
), "%08x", rid
);
290 sid_name_use
= SID_NAME_UNKNOWN
;
293 make_lsa_trans_name(&(trn
->name
[total
]),
294 &(trn
->uni_name
[total
]),
295 sid_name_use
, name
, dom_idx
);
299 trn
->num_entries
= total
;
300 trn
->ptr_trans_names
= 1;
301 trn
->num_entries2
= total
;
304 /***************************************************************************
305 make_reply_lookup_sids
306 ***************************************************************************/
307 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS
*r_l
,
308 DOM_R_REF
*ref
, LSA_TRANS_NAME_ENUM
*names
,
309 uint32 mapped_count
, uint32 status
)
313 r_l
->mapped_count
= mapped_count
;
314 r_l
->status
= status
;
317 /***************************************************************************
318 lsa_reply_lookup_sids
319 ***************************************************************************/
320 static void lsa_reply_lookup_sids(prs_struct
*rdata
,
321 DOM_SID2
*sid
, int num_entries
)
323 LSA_R_LOOKUP_SIDS r_l
;
325 LSA_TRANS_NAME_ENUM names
;
326 uint32 mapped_count
= 0;
332 /* set up the LSA Lookup SIDs response */
333 make_lsa_trans_names(&ref
, &names
, num_entries
, sid
, &mapped_count
);
334 make_reply_lookup_sids(&r_l
, &ref
, &names
, mapped_count
, 0x0);
336 /* store the response in the SMB stream */
337 lsa_io_r_lookup_sids("", &r_l
, rdata
, 0);
340 /***************************************************************************
341 lsa_reply_lookup_names
342 ***************************************************************************/
343 static void lsa_reply_lookup_names(prs_struct
*rdata
,
345 DOM_SID dom_sids
[MAX_LOOKUP_SIDS
],
346 uint8 dom_types
[MAX_LOOKUP_SIDS
])
348 LSA_R_LOOKUP_NAMES r_l
;
352 /* set up the LSA Lookup RIDs response */
353 make_reply_lookup_names(&r_l
, num_entries
, dom_sids
, dom_types
);
357 /* store the response in the SMB stream */
358 lsa_io_r_lookup_names("", &r_l
, rdata
, 0);
361 /***************************************************************************
363 ***************************************************************************/
364 static void api_lsa_open_policy2( uint16 vuid
, prs_struct
*data
,
371 /* grab the server, object attributes and desired access flag...*/
372 lsa_io_q_open_pol2("", &q_o
, data
, 0);
374 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
376 /* return a 20 byte policy handle */
377 lsa_reply_open_policy2(rdata
);
380 /***************************************************************************
382 ***************************************************************************/
383 static void api_lsa_open_policy( uint16 vuid
, prs_struct
*data
,
390 /* grab the server, object attributes and desired access flag...*/
391 lsa_io_q_open_pol("", &q_o
, data
, 0);
393 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
395 /* return a 20 byte policy handle */
396 lsa_reply_open_policy(rdata
);
399 /***************************************************************************
400 api_lsa_enum_trust_dom
401 ***************************************************************************/
402 static void api_lsa_enum_trust_dom( uint16 vuid
, prs_struct
*data
,
405 LSA_Q_ENUM_TRUST_DOM q_e
;
409 /* grab the enum trust domain context etc. */
410 lsa_io_q_enum_trust_dom("", &q_e
, data
, 0);
412 /* construct reply. return status is always 0x0 */
413 lsa_reply_enum_trust_dom(&q_e
, rdata
, 0, NULL
, NULL
);
416 /***************************************************************************
418 ***************************************************************************/
419 static void api_lsa_query_info( uint16 vuid
, prs_struct
*data
,
422 LSA_Q_QUERY_INFO q_i
;
425 memset(name
, 0, sizeof(name
));
429 /* grab the info class and policy handle */
430 lsa_io_q_query("", &q_i
, data
, 0);
432 switch (q_i
.info_class
)
436 fstrcpy(name
, global_myworkgroup
);
437 sid
= &global_member_sid
;
442 fstrcpy(name
, global_sam_name
);
443 sid
= &global_sam_sid
;
448 DEBUG(5,("unknown info level in Lsa Query: %d\n",
454 /* construct reply. return status is always 0x0 */
455 lsa_reply_query_info(&q_i
, rdata
, name
, sid
);
458 /***************************************************************************
460 ***************************************************************************/
461 static void api_lsa_lookup_sids( uint16 vuid
, prs_struct
*data
,
464 LSA_Q_LOOKUP_SIDS q_l
;
467 /* grab the info class and policy handle */
468 lsa_io_q_lookup_sids("", &q_l
, data
, 0);
470 /* construct reply. return status is always 0x0 */
471 lsa_reply_lookup_sids(rdata
, q_l
.sids
.sid
, q_l
.sids
.num_entries
);
474 /***************************************************************************
476 ***************************************************************************/
477 static void api_lsa_lookup_names( uint16 vuid
, prs_struct
*data
,
481 LSA_Q_LOOKUP_NAMES q_l
;
482 DOM_SID dom_sids
[MAX_LOOKUP_SIDS
];
483 uint8 dom_types
[MAX_LOOKUP_SIDS
];
486 ZERO_ARRAY(dom_sids
);
488 /* grab the info class and policy handle */
489 lsa_io_q_lookup_names("", &q_l
, data
, 0);
491 SMB_ASSERT_ARRAY(q_l
.uni_name
, q_l
.num_entries
);
493 /* convert received RIDs to strings, so we can do them. */
494 for (i
= 0; i
< q_l
.num_entries
; i
++)
497 fstrcpy(name
, unistr2_to_str(&q_l
.uni_name
[i
]));
499 if (!lookup_name(name
, &dom_sids
[i
], &dom_types
[i
]))
501 dom_types
[i
] = SID_NAME_UNKNOWN
;
505 /* construct reply. return status is always 0x0 */
506 lsa_reply_lookup_names(rdata
,
508 dom_sids
, /* text-converted SIDs */
509 dom_types
); /* SID_NAME_USE types */
512 /***************************************************************************
514 ***************************************************************************/
515 static void api_lsa_close( uint16 vuid
, prs_struct
*data
,
518 /* XXXX this is NOT good */
519 char *q
= mem_data(&(rdata
->data
), rdata
->offset
);
537 /***************************************************************************
539 ***************************************************************************/
540 static void api_lsa_open_secret( uint16 vuid
, prs_struct
*data
,
543 /* XXXX this is NOT good */
544 char *q
= mem_data(&(rdata
->data
), rdata
->offset
);
556 SIVAL(q
, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND
);
562 /***************************************************************************
564 ***************************************************************************/
565 static struct api_struct api_lsa_cmds
[] =
567 { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2
, api_lsa_open_policy2
},
568 { "LSA_OPENPOLICY" , LSA_OPENPOLICY
, api_lsa_open_policy
},
569 { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY
, api_lsa_query_info
},
570 { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM
, api_lsa_enum_trust_dom
},
571 { "LSA_CLOSE" , LSA_CLOSE
, api_lsa_close
},
572 { "LSA_OPENSECRET" , LSA_OPENSECRET
, api_lsa_open_secret
},
573 { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS
, api_lsa_lookup_sids
},
574 { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES
, api_lsa_lookup_names
},
578 /***************************************************************************
580 ***************************************************************************/
581 BOOL
api_ntlsa_rpc(pipes_struct
*p
, prs_struct
*data
)
583 return api_rpcTNP(p
, "api_ntlsa_rpc", api_lsa_cmds
, data
);