3 * Unix SMB/Netbios implementation.
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.
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.
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.
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.
29 this module provides nt user / nt rid lookup functions.
30 users, local groups, domain groups.
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.
37 did i say rids? oops, what about "S-1-1" the "Everyone" group
38 and other such well-known sids...
40 speed is not of the essence: no particular optimisation is in place.
49 extern int DEBUGLEVEL
;
51 extern fstring global_sam_name
;
52 extern DOM_SID global_sam_sid
;
53 extern DOM_SID global_sid_S_1_5_20
;
56 * A list of the rids of well known BUILTIN and Domain users
60 rid_name builtin_alias_rids
[] =
62 { BUILTIN_ALIAS_RID_ADMINS
, "Administrators" },
63 { BUILTIN_ALIAS_RID_USERS
, "Users" },
64 { BUILTIN_ALIAS_RID_GUESTS
, "Guests" },
65 { BUILTIN_ALIAS_RID_POWER_USERS
, "Power Users" },
67 { BUILTIN_ALIAS_RID_ACCOUNT_OPS
, "Account Operators" },
68 { BUILTIN_ALIAS_RID_SYSTEM_OPS
, "System Operators" },
69 { BUILTIN_ALIAS_RID_PRINT_OPS
, "Print Operators" },
70 { BUILTIN_ALIAS_RID_BACKUP_OPS
, "Backup Operators" },
71 { BUILTIN_ALIAS_RID_REPLICATOR
, "Replicator" },
75 /* array lookup of well-known Domain RID users. */
76 rid_name domain_user_rids
[] =
78 { DOMAIN_USER_RID_ADMIN
, "Administrator" },
79 { DOMAIN_USER_RID_GUEST
, "Guest" },
83 /* array lookup of well-known Domain RID groups. */
84 rid_name domain_group_rids
[] =
86 { DOMAIN_GROUP_RID_ADMINS
, "Domain Admins" },
87 { DOMAIN_GROUP_RID_USERS
, "Domain Users" },
88 { DOMAIN_GROUP_RID_GUESTS
, "Domain Guests" },
93 int make_dom_gids(DOMAIN_GRP
*mem
, int num_members
, DOM_GID
**ppgids
)
101 DEBUG(4,("make_dom_gids: %d\n", num_members
));
103 if (mem
== NULL
|| num_members
== 0)
108 for (i
= 0, count
= 0; i
< num_members
&& count
< LSA_MAX_GROUPS
; i
++)
115 uint8 attr
= mem
[count
].attr
;
116 char *name
= mem
[count
].name
;
119 status
= lookup_grp_rid(name
, &rid
, &type
);
124 gids
= (DOM_GID
*)Realloc( gids
, sizeof(DOM_GID
) * (count
+1) );
128 DEBUG(0,("make_dom_gids: Realloc fail !\n"));
132 gids
[count
].g_rid
= rid
;
133 gids
[count
].attr
= attr
;
135 DEBUG(5,("group name: %s rid: %d attr: %d\n",
141 DEBUG(1,("make_dom_gids: unknown group name %s\n", name
));
149 /*******************************************************************
150 gets a domain user's groups
151 ********************************************************************/
152 int get_domain_user_groups(DOMAIN_GRP_MEMBER
**grp_members
, uint32 group_rid
)
157 if (grp_members
== NULL
) return 0;
159 grp
= getgrouprid(group_rid
, grp_members
, &num_mem
);
170 /*******************************************************************
172 ********************************************************************/
173 uint32
lookup_builtin_names(uint32 rid
, char *name
, uint8
*type
)
175 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
177 status
= (status
!= 0x0) ? lookup_wk_user_name (rid
, name
, type
) : status
;
178 status
= (status
!= 0x0) ? lookup_wk_group_name(rid
, name
, type
) : status
;
179 status
= (status
!= 0x0) ? lookup_wk_alias_name(rid
, name
, type
) : status
;
185 /*******************************************************************
186 lookup_added_name - names that have been added to the SAM database by admins.
187 ********************************************************************/
188 uint32
lookup_added_name(uint32 rid
, char *name
, uint8
*type
)
190 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
192 status
= (status
!= 0x0) ? lookup_user_name (rid
, name
, type
) : status
;
193 status
= (status
!= 0x0) ? lookup_group_name(rid
, name
, type
) : status
;
194 status
= (status
!= 0x0) ? lookup_alias_name(rid
, name
, type
) : status
;
200 /*******************************************************************
202 ********************************************************************/
203 uint32
lookup_name(uint32 rid
, char *name
, uint8
*type
)
205 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
207 status
= (status
!= 0x0) ? lookup_builtin_names(rid
, name
, type
) : status
;
208 status
= (status
!= 0x0) ? lookup_added_name (rid
, name
, type
) : status
;
214 /*******************************************************************
216 ********************************************************************/
217 uint32
lookup_wk_group_name(uint32 rid
, char *group_name
, uint8
*type
)
220 (*type
) = SID_NAME_WKN_GRP
;
222 DEBUG(5,("lookup_wk_group_name: rid: %d", rid
));
224 while (domain_group_rids
[i
].rid
!= rid
&& domain_group_rids
[i
].rid
!= 0)
229 if (domain_group_rids
[i
].rid
!= 0)
231 fstrcpy(group_name
, domain_group_rids
[i
].name
);
232 DEBUG(5,(" = %s\n", group_name
));
236 DEBUG(5,(" none mapped\n"));
237 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
240 /*******************************************************************
242 ********************************************************************/
243 uint32
lookup_group_name(uint32 rid
, char *group_name
, uint8
*type
)
245 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
248 DEBUG(5,("lookup_group_name: rid: 0x%x", rid
));
250 sid_copy (&sid
, &global_sam_sid
);
251 sid_append_rid(&sid
, rid
);
253 (*type
) = SID_NAME_DOM_GRP
;
255 if (map_group_sid_to_name(&sid
, group_name
, NULL
))
262 DEBUG(5,(" = %s\n", group_name
));
266 DEBUG(5,(" none mapped\n"));
272 /*******************************************************************
274 ********************************************************************/
275 uint32
lookup_wk_alias_name(uint32 rid
, char *alias_name
, uint8
*type
)
278 (*type
) = SID_NAME_ALIAS
;
280 DEBUG(5,("lookup_wk_alias_name: rid: %d", rid
));
282 while (builtin_alias_rids
[i
].rid
!= rid
&& builtin_alias_rids
[i
].rid
!= 0)
287 if (builtin_alias_rids
[i
].rid
!= 0)
289 fstrcpy(alias_name
, builtin_alias_rids
[i
].name
);
290 DEBUG(5,(" = %s\n", alias_name
));
294 DEBUG(5,(" none mapped\n"));
295 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
298 /*******************************************************************
300 ********************************************************************/
301 uint32
lookup_alias_name(uint32 rid
, char *alias_name
, uint8
*type
)
303 (*type
) = SID_NAME_ALIAS
;
305 DEBUG(2,("lookup_alias_name: rid: %d\n", rid
));
306 DEBUG(2,(" NOT IMPLEMENTED\n"));
308 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
311 /*******************************************************************
312 lookup well-known user name
313 ********************************************************************/
314 uint32
lookup_wk_user_name(uint32 rid
, char *user_name
, uint8
*type
)
317 (*type
) = SID_NAME_USER
;
319 DEBUG(5,("lookup_wk_user_name: rid: %d", rid
));
321 /* look up the well-known domain user rids first */
322 while (domain_user_rids
[i
].rid
!= rid
&& domain_user_rids
[i
].rid
!= 0)
327 if (domain_user_rids
[i
].rid
!= 0)
329 fstrcpy(user_name
, domain_user_rids
[i
].name
);
330 DEBUG(5,(" = %s\n", user_name
));
334 DEBUG(5,(" none mapped\n"));
335 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
338 /*******************************************************************
340 ********************************************************************/
341 uint32
lookup_user_name(uint32 rid
, char *user_name
, uint8
*type
)
343 struct sam_disp_info
*disp_info
;
344 (*type
) = SID_NAME_USER
;
346 DEBUG(5,("lookup_user_name: rid: %d", rid
));
348 /* find the user account */
350 disp_info
= getsamdisprid(rid
);
353 if (disp_info
!= NULL
)
355 fstrcpy(user_name
, disp_info
->smb_name
);
356 DEBUG(5,(" = %s\n", user_name
));
360 DEBUG(5,(" none mapped\n"));
361 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
364 /*******************************************************************
366 ********************************************************************/
367 uint32
lookup_group_rid(char *group_name
, uint32
*rid
, uint8
*type
)
372 (*type
) = SID_NAME_DOM_GRP
;
374 DEBUG(5,("lookup_group_rid: name: %s", group_name
));
376 if (map_group_name_to_sid(group_name
, &sid
) &&
377 sid_split_rid(&sid
, rid
) &&
378 sid_equal(&sid
, &global_sam_sid
))
380 DEBUG(5,(" = 0x%x\n", (*rid
)));
384 DEBUG(5,(" none mapped\n"));
385 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
388 /*******************************************************************
390 ********************************************************************/
391 uint32
lookup_wk_group_rid(char *group_name
, uint32
*rid
, uint8
*type
)
394 int i
= -1; /* start do loop at -1 */
396 (*type
) = SID_NAME_WKN_GRP
;
398 do /* find, if it exists, a group rid for the group name */
401 (*rid
) = domain_group_rids
[i
].rid
;
402 grp_name
= domain_group_rids
[i
].name
;
404 } while (grp_name
!= NULL
&& !strequal(grp_name
, group_name
));
406 return (grp_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
409 /*******************************************************************
411 ********************************************************************/
412 uint32
lookup_alias_sid(char *alias_name
, DOM_SID
*sid
, uint8
*type
)
414 (*type
) = SID_NAME_ALIAS
;
416 DEBUG(5,("lookup_alias_rid: name: %s", alias_name
));
418 if (map_alias_name_to_sid(alias_name
, sid
))
421 sid_to_string(sid_str
, sid
);
422 DEBUG(5,(" = %s\n", sid_str
));
426 DEBUG(5,(" none mapped\n"));
427 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
430 /*******************************************************************
432 ********************************************************************/
433 uint32
lookup_alias_rid(char *alias_name
, uint32
*rid
, uint8
*type
)
438 (*type
) = SID_NAME_ALIAS
;
440 DEBUG(5,("lookup_alias_rid: name: %s", alias_name
));
442 if (map_alias_name_to_sid(alias_name
, &sid
) &&
443 sid_split_rid(&sid
, rid
) &&
444 sid_equal(&sid
, &global_sam_sid
))
446 DEBUG(5,(" = 0x%x\n", (*rid
)));
450 DEBUG(5,(" none mapped\n"));
451 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
454 /*******************************************************************
456 ********************************************************************/
457 uint32
lookup_wk_alias_sid(char *alias_name
, DOM_SID
*sid
, uint8
*type
)
462 (*type
) = SID_NAME_ALIAS
;
464 do /* find, if it exists, a alias rid for the alias name*/
466 rid
= builtin_alias_rids
[i
].rid
;
467 als_name
= builtin_alias_rids
[i
].name
;
471 if (strequal(als_name
, alias_name
))
473 sid_copy(sid
, &global_sid_S_1_5_20
);
474 sid_append_rid(sid
, rid
);
479 } while (als_name
!= NULL
);
481 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
484 /*******************************************************************
486 ********************************************************************/
487 uint32
lookup_wk_alias_rid(char *alias_name
, uint32
*rid
, uint8
*type
)
490 int i
= -1; /* start do loop at -1 */
492 (*type
) = SID_NAME_ALIAS
;
494 do /* find, if it exists, a alias rid for the alias name*/
497 (*rid
) = builtin_alias_rids
[i
].rid
;
498 als_name
= builtin_alias_rids
[i
].name
;
500 } while (als_name
!= NULL
&& !strequal(als_name
, alias_name
));
502 return (als_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
505 /*******************************************************************
507 ********************************************************************/
508 uint32
lookup_sid(char *name
, DOM_SID
*sid
, uint8
*type
)
510 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
514 split_domain_name(name
, domain
, user
);
516 if (!strequal(domain
, global_sam_name
))
518 DEBUG(0,("lookup_sid: remote domain %s not supported\n", domain
));
522 status
= (status
!= 0x0) ? lookup_wk_alias_sid(user
, sid
, type
) : status
;
523 status
= (status
!= 0x0) ? lookup_alias_sid (user
, sid
, type
) : status
;
525 status
= (status
!= 0x0) ? lookup_domain_sid (user
, sid
, type
) : status
;
531 /*******************************************************************
532 lookup_added_user_rid
533 ********************************************************************/
534 uint32
lookup_added_user_rids(char *user_name
,
535 uint32
*usr_rid
, uint32
*grp_rid
)
537 struct sam_passwd
*sam_pass
;
541 /* find the user account */
543 sam_pass
= getsam21pwnam(user_name
);
546 if (sam_pass
!= NULL
)
548 (*usr_rid
) = sam_pass
->user_rid
;
549 (*grp_rid
) = sam_pass
->group_rid
;
553 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
556 /*******************************************************************
557 lookup_added_user_rid
558 ********************************************************************/
559 uint32
lookup_added_user_rid(char *user_name
, uint32
*rid
, uint8
*type
)
561 struct sam_passwd
*sam_pass
;
563 (*type
) = SID_NAME_USER
;
565 /* find the user account */
567 sam_pass
= getsam21pwnam(user_name
);
570 if (sam_pass
!= NULL
)
572 (*rid
) = sam_pass
->user_rid
;
576 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
579 /*******************************************************************
581 ********************************************************************/
582 uint32
lookup_wk_user_rid(char *user_name
, uint32
*rid
, uint8
*type
)
585 int i
= -1; /* start do loop at -1 */
587 (*type
) = SID_NAME_USER
;
589 do /* find, if it exists, a alias rid for the alias name*/
592 (*rid
) = domain_user_rids
[i
].rid
;
593 usr_name
= domain_user_rids
[i
].name
;
595 } while (usr_name
!= NULL
&& !strequal(usr_name
, user_name
));
597 return (usr_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
600 /*******************************************************************
602 ********************************************************************/
603 uint32
lookup_added_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
605 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
607 status
= (status
!= 0x0) ? lookup_group_rid(name
, rid
, type
) : status
;
608 status
= (status
!= 0x0) ? lookup_alias_rid(name
, rid
, type
) : status
;
613 /*******************************************************************
614 lookup_builtin_grp_rid
615 ********************************************************************/
616 uint32
lookup_builtin_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
618 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
620 status
= (status
!= 0x0) ? lookup_wk_group_rid(name
, rid
, type
) : status
;
621 status
= (status
!= 0x0) ? lookup_wk_alias_rid(name
, rid
, type
) : status
;
626 /*******************************************************************
628 ********************************************************************/
629 uint32
lookup_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
631 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
633 status
= (status
!= 0x0) ? lookup_builtin_grp_rid(name
, rid
, type
) : status
;
634 status
= (status
!= 0x0) ? lookup_added_grp_rid (name
, rid
, type
) : status
;
639 /*******************************************************************
641 ********************************************************************/
642 uint32
lookup_user_rid(char *name
, uint32
*rid
, uint8
*type
)
644 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
646 status
= (status
!= 0x0) ? lookup_wk_user_rid (name
, rid
, type
) : status
;
647 status
= (status
!= 0x0) ? lookup_added_user_rid(name
, rid
, type
) : status
;
652 /*******************************************************************
654 ********************************************************************/
655 uint32
lookup_rid(char *name
, uint32
*rid
, uint8
*type
)
657 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
659 status
= (status
!= 0x0) ? lookup_user_rid(name
, rid
, type
) : status
;
660 status
= (status
!= 0x0) ? lookup_grp_rid (name
, rid
, type
) : status
;
665 /*******************************************************************
667 ********************************************************************/
668 uint32
lookup_user_rids(char *name
, uint32
*usr_rid
, uint32
*grp_rid
)
670 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
674 * try an ordinary user lookup
677 status
= lookup_added_user_rids(name
, usr_rid
, grp_rid
);
684 * hm. must be a well-known user, in a well-known group.
687 status
= lookup_wk_user_rid(name
, usr_rid
, &type
);
688 if (status
!= 0 || type
!= SID_NAME_USER
)
690 return status
; /* ok, maybe not! */
692 if (type
!= SID_NAME_USER
)
694 return 0xC0000000 | NT_STATUS_NONE_MAPPED
; /* users only... */
698 * ok, got the user rid: now try the group rid
701 status
= lookup_builtin_grp_rid(name
, grp_rid
, &type
);
702 if (type
== SID_NAME_DOM_GRP
||
703 type
== SID_NAME_ALIAS
||
704 type
== SID_NAME_WKN_GRP
)
706 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;