fix for enumerate domain users (bug spotted by sean matthews).
[samba.git] / source3 / rpc_server / srv_lookup.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1998
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                  1997-1998.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /*
26  *
27  *
28
29  this module provides nt user / nt rid lookup functions.
30  users, local groups, domain groups.
31
32  no unix / samba functions should be called in this module:
33  it should purely provide a gateway to the password database API,
34  the local group database API or the domain group database API,
35  but first checking built-in rids.
36
37  did i say rids?  oops, what about "S-1-1" the "Everyone" group
38  and other such well-known sids...
39
40  speed is not of the essence: no particular optimisation is in place.
41
42  *
43  *
44  */
45
46 #include "includes.h"
47 #include "nterr.h"
48
49 extern int DEBUGLEVEL;
50
51 extern fstring global_sam_name;
52 extern DOM_SID global_sam_sid;
53 extern DOM_SID global_sid_S_1_5_20;
54
55 extern rid_name builtin_alias_rids[];
56 extern rid_name domain_user_rids[];
57 extern rid_name domain_group_rids[];
58
59 int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
60 {
61         int count;
62         int i;
63         DOM_GID *gids = NULL;
64
65         *ppgids = NULL;
66
67         DEBUG(4,("make_dom_gids: %d\n", num_members));
68
69         if (mem == NULL || num_members == 0)
70         {
71                 return 0;
72         }
73
74         for (i = 0, count = 0; i < num_members && count < LSA_MAX_GROUPS; i++) 
75         {
76                 uint32 status;
77
78                 uint32 rid;
79                 DOM_SID sid;
80                 uint8  type;
81
82                 uint8  attr  = mem[count].attr;
83                 char   *name = mem[count].name;
84
85                 become_root(True);
86                 status = lookup_name(name, &sid, &type);
87                 unbecome_root(True);
88
89                 if (status == 0x0 && !sid_front_equal(&global_sam_sid, &sid))
90                 {
91                         fstring sid_str;
92                         sid_to_string(sid_str, &sid);
93                         DEBUG(1,("make_dom_gids: unknown sid %s for groupname %s\n",
94                                   sid_str, name));
95                 }
96                 else if (status == 0x0)
97                 {
98                         sid_split_rid(&sid, &rid);
99
100                         gids = (DOM_GID *)Realloc( gids, sizeof(DOM_GID) * (count+1) );
101
102                         if (gids == NULL)
103                         {
104                                 DEBUG(0,("make_dom_gids: Realloc fail !\n"));
105                                 return 0;
106                         }
107
108                         gids[count].g_rid = rid;
109                         gids[count].attr  = attr;
110
111                         DEBUG(5,("group name: %s rid: %d attr: %d\n",
112                                   name, rid, attr));
113                         count++;
114                 }
115                 else
116                 {
117                         DEBUG(1,("make_dom_gids: unknown groupname %s\n", name));
118                 }
119         }
120
121         *ppgids = gids;
122         return count;
123 }
124
125 /*******************************************************************
126  gets a domain user's groups
127  ********************************************************************/
128 int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid)
129 {
130         DOMAIN_GRP *grp;
131         int num_mem;
132
133         if (grp_members == NULL) return 0;
134
135         grp = getgrouprid(group_rid, grp_members, &num_mem);
136
137         if (grp == NULL)
138         {
139                 return 0;
140         }
141
142         return num_mem;
143 }
144
145
146 /*******************************************************************
147  lookup_builtin_sid
148  ********************************************************************/
149 uint32 lookup_builtin_sid(DOM_SID *sid, char *name, uint8 *type)
150 {
151         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
152
153         status = (status != 0x0) ? lookup_wk_user_sid (sid, name, type) : status;
154         status = (status != 0x0) ? lookup_wk_group_sid(sid, name, type) : status;
155         status = (status != 0x0) ? lookup_wk_alias_sid(sid, name, type) : status;
156
157         return status;
158 }
159
160
161 /*******************************************************************
162  lookup_added_sid - names that have been added to the SAM database by admins.
163  ********************************************************************/
164 uint32 lookup_added_sid(DOM_SID *sid, char *name, uint8 *type)
165 {
166         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
167
168         status = (status != 0x0) ? lookup_user_sid (sid, name, type) : status;
169         status = (status != 0x0) ? lookup_group_sid(sid, name, type) : status;
170         status = (status != 0x0) ? lookup_alias_sid(sid, name, type) : status;
171
172         return status;
173 }
174
175
176 /*******************************************************************
177  lookup_sid
178  ********************************************************************/
179 uint32 lookup_sid(DOM_SID *sid, char *name, uint8 *type)
180 {
181         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
182
183         status = (status != 0x0) ? lookup_builtin_sid(sid, name, type) : status;
184         status = (status != 0x0) ? lookup_added_sid   (sid, name, type) : status;
185
186         return status;
187 }
188
189
190 /*******************************************************************
191  lookup_wk_group_sid
192  ********************************************************************/
193 uint32 lookup_wk_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
194 {
195         int i = 0; 
196         uint32 rid;
197         DOM_SID tmp;
198
199         (*type) = SID_NAME_WKN_GRP;
200
201         sid_copy(&tmp, sid);
202         sid_split_rid(&tmp, &rid);
203
204         if (!sid_equal(&global_sid_S_1_5_20, &tmp))
205         {
206                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
207         }
208
209         DEBUG(5,("lookup_wk_group_sid: rid: %d", rid));
210
211         while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
212         {
213                 i++;
214         }
215
216         if (domain_group_rids[i].rid != 0)
217         {
218                 fstrcpy(group_name, domain_group_rids[i].name);
219                 DEBUG(5,(" = %s\n", group_name));
220                 return 0x0;
221         }
222
223         DEBUG(5,(" none mapped\n"));
224         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
225 }
226
227 /*******************************************************************
228  lookup_group_sid
229  ********************************************************************/
230 uint32 lookup_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
231 {
232         pstring sid_str;
233         uint32 rid;
234         DOM_SID tmp;
235         DOMAIN_GRP *grp = NULL;
236         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
237
238         (*type) = SID_NAME_DOM_GRP;
239
240         sid_to_string(sid_str, sid);
241         DEBUG(5,("lookup_group_sid: sid: %s", sid_str));
242
243         sid_copy(&tmp, sid);
244         sid_split_rid(&tmp, &rid);
245
246         if (!sid_equal(&global_sam_sid, &tmp))
247         {
248                 DEBUG(5,("not our SID\n"));
249                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
250         }
251
252         grp = getgrouprid(rid, NULL, NULL);
253
254         if (grp != NULL)
255         {
256                 fstrcpy(group_name, grp->name);
257                 DEBUG(5,(" = %s\n", group_name));
258                 return 0x0;
259         }
260
261         DEBUG(5,(" none mapped\n"));
262         return status;
263 }
264
265 /*******************************************************************
266  lookup_wk_alias_sid
267  ********************************************************************/
268 uint32 lookup_wk_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
269 {
270         int i = 0; 
271         uint32 rid;
272         DOM_SID tmp;
273
274         (*type) = SID_NAME_ALIAS;
275
276         sid_copy(&tmp, sid);
277         sid_split_rid(&tmp, &rid);
278
279         if (!sid_equal(&global_sid_S_1_5_20, &tmp))
280         {
281                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
282         }
283
284         DEBUG(5,("lookup_wk_alias_sid: rid: %d", rid));
285
286         while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
287         {
288                 i++;
289         }
290
291         if (builtin_alias_rids[i].rid != 0)
292         {
293                 fstrcpy(alias_name, builtin_alias_rids[i].name);
294                 DEBUG(5,(" = %s\n", alias_name));
295                 return 0x0;
296         }
297
298         DEBUG(5,(" none mapped\n"));
299         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
300 }
301
302 /*******************************************************************
303  lookup_alias_sid
304  ********************************************************************/
305 uint32 lookup_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
306 {
307         pstring sid_str;
308         uint32 rid;
309         DOM_SID tmp;
310         LOCAL_GRP *als = NULL;
311         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
312
313         (*type) = SID_NAME_ALIAS;
314
315         sid_to_string(sid_str, sid);
316         DEBUG(5,("lookup_alias_sid: sid: %s", sid_str));
317
318         sid_copy(&tmp, sid);
319         sid_split_rid(&tmp, &rid);
320
321         if (!sid_equal(&global_sam_sid, &tmp))
322         {
323                 DEBUG(5,("not our SID\n"));
324                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
325         }
326
327         als = getaliasrid(rid, NULL, NULL);
328
329         if (als != NULL)
330         {
331                 fstrcpy(alias_name, als->name);
332                 DEBUG(5,(" = %s\n", alias_name));
333                 return 0x0;
334         }
335
336         DEBUG(5,(" none mapped\n"));
337         return status;
338 }
339
340 /*******************************************************************
341  lookup well-known user name
342  ********************************************************************/
343 uint32 lookup_wk_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
344 {
345         int i = 0;
346         uint32 rid;
347         DOM_SID tmp;
348
349         (*type) = SID_NAME_USER;
350
351         sid_copy(&tmp, sid);
352         sid_split_rid(&tmp, &rid);
353
354         if (!sid_equal(&global_sid_S_1_5_20, &tmp))
355         {
356                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
357         }
358
359         DEBUG(5,("lookup_wk_user_sid: rid: %d", rid));
360
361         /* look up the well-known domain user rids first */
362         while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
363         {
364                 i++;
365         }
366
367         if (domain_user_rids[i].rid != 0)
368         {
369                 fstrcpy(user_name, domain_user_rids[i].name);
370                 DEBUG(5,(" = %s\n", user_name));
371                 return 0x0;
372         }
373
374         DEBUG(5,(" none mapped\n"));
375         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
376 }
377
378 /*******************************************************************
379  lookup user name
380  ********************************************************************/
381 uint32 lookup_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
382 {
383         struct sam_disp_info *disp_info;
384         uint32 rid;
385         DOM_SID tmp;
386
387         (*type) = SID_NAME_USER;
388
389         sid_copy(&tmp, sid);
390         sid_split_rid(&tmp, &rid);
391
392         if (sid_equal(&global_sam_sid, &tmp))
393         {
394                 DEBUG(5,("lookup_user_sid in SAM %s: rid: %d",
395                           global_sam_name, rid));
396
397                 /* find the user account */
398                 become_root(True);
399                 disp_info = getsamdisprid(rid);
400                 unbecome_root(True);
401
402                 if (disp_info != NULL)
403                 {
404                         fstrcpy(user_name, disp_info->nt_name);
405                         DEBUG(5,(" = %s\n", user_name));
406                         return 0x0;
407                 }
408
409                 DEBUG(5,(" none mapped\n"));
410         }
411
412         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
413 }
414
415 /*******************************************************************
416  lookup_group_rid
417  ********************************************************************/
418 uint32 lookup_added_group_name(const char *grp_name, const char *domain,
419                                 DOM_SID *sid, uint8 *type)
420 {
421         DOMAIN_GRP *grp = NULL;
422         (*type) = SID_NAME_DOM_GRP;
423
424         DEBUG(5,("lookup_added_group_name: name: %s", grp_name));
425
426         if (!strequal(domain, global_sam_name))
427         {
428                 DEBUG(5,(" not our domain\n"));
429                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
430         }
431
432         grp = getgroupntnam(grp_name, NULL, NULL);
433
434         if (grp != NULL)
435         {
436                 sid_copy(sid, &global_sam_sid);
437                 sid_append_rid(sid, grp->rid);
438
439                 DEBUG(5,(" = 0x%x\n", grp->rid));
440                 return 0x0;
441         }
442
443         DEBUG(5,(" none mapped\n"));
444         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
445 }
446
447 /*******************************************************************
448  lookup_added_alias_name
449  ********************************************************************/
450 uint32 lookup_added_alias_name(const char *als_name, const char *domain,
451                                 DOM_SID *sid, uint8 *type)
452 {
453         LOCAL_GRP *als = NULL;
454         (*type) = SID_NAME_ALIAS;
455
456         DEBUG(5,("lookup_added_alias_name: name: %s\\%s", domain, als_name));
457
458         if (!strequal(domain, global_sam_name))
459         {
460                 DEBUG(5,(" not our domain\n"));
461                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
462         }
463
464         als = getaliasntnam(als_name, NULL, NULL);
465
466         if (als != NULL)
467         {
468                 sid_copy(sid, &global_sam_sid);
469                 sid_append_rid(sid, als->rid);
470
471                 DEBUG(5,(" = 0x%x\n", als->rid));
472                 return 0x0;
473         }
474
475         DEBUG(5,(" none mapped\n"));
476         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
477 }
478
479 /*******************************************************************
480  lookup_added_user_rid
481  ********************************************************************/
482 uint32 lookup_added_user_rids(char *nt_name,
483                 uint32 *usr_rid, uint32 *grp_rid)
484 {
485         struct sam_passwd *sam_pass;
486         (*usr_rid) = 0;
487         (*grp_rid) = 0;
488
489         /* find the user account */
490         become_root(True);
491         sam_pass = getsam21pwntnam(nt_name);
492         unbecome_root(True);
493
494         if (sam_pass != NULL)
495         {
496                 (*usr_rid) = sam_pass->user_rid ;
497                 (*grp_rid) = sam_pass->group_rid;
498                 return 0x0;
499         }
500
501         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
502 }
503
504 /*******************************************************************
505  lookup_added_user_name
506  ********************************************************************/
507 static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
508                                 DOM_SID *sid, uint8 *type)
509 {
510         struct sam_passwd *sam_pass;
511         (*type) = SID_NAME_USER;
512
513         if (!strequal(domain, global_sam_name))
514         {
515                 return 0xC0000000 | NT_STATUS_NONE_MAPPED;
516         }
517
518         /* find the user account */
519         become_root(True);
520         sam_pass = getsam21pwntnam(nt_name);
521         unbecome_root(True);
522
523         if (sam_pass != NULL)
524         {
525                 sid_copy(sid, &global_sam_sid);
526                 sid_append_rid(sid, sam_pass->user_rid);
527
528                 return 0x0;
529         }
530
531         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
532 }
533
534 /*******************************************************************
535  lookup_grp_name
536  ********************************************************************/
537 static uint32 lookup_grp_name(const char *name, const char *domain,
538                                 DOM_SID *sid, uint8 *type)
539 {
540         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
541
542         status = (status != 0x0) ? lookup_wk_group_name     (name, domain, sid, type) : status;
543         status = (status != 0x0) ? lookup_builtin_alias_name(name, domain, sid, type) : status;
544         status = (status != 0x0) ? lookup_added_group_name  (name, domain, sid, type) : status;
545         status = (status != 0x0) ? lookup_added_alias_name  (name, domain, sid, type) : status;
546
547         return status;
548 }
549
550 /*******************************************************************
551  lookup_user_name
552  ********************************************************************/
553 static uint32 lookup_user_name(const char *name, const char *domain,
554                                 DOM_SID *sid, uint8 *type)
555 {
556         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
557
558         status = (status != 0x0) ? lookup_wk_user_name   (name, domain, sid, type) : status;
559         status = (status != 0x0) ? lookup_added_user_name(name, domain, sid, type) : status;
560
561         return status;
562 }
563
564 /*******************************************************************
565  lookup_name
566  ********************************************************************/
567 uint32 lookup_name(char *name, DOM_SID *sid, uint8 *type)
568 {
569         uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
570         fstring domain;
571         fstring user;
572         
573         split_domain_name(name, domain, user);
574
575         status = (status != 0x0) ? lookup_user_name    (user, domain, sid, type) : status;
576         status = (status != 0x0) ? lookup_grp_name     (user, domain, sid, type) : status;
577 #if 0
578         status = (status != 0x0) ? lookup_domain_name  (domain, sid, type) : status;
579 #endif
580
581         return status;
582 }
583