2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1998
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
7 * Copyright (C) Paul Ashton 1997-1998.
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.
28 this module provides nt user / nt rid lookup functions.
29 users, local groups, domain groups.
31 no unix / samba functions should be called in this module:
32 it should purely provide a gateway to the password database API,
33 the local group database API or the domain group database API,
34 but first checking built-in rids.
36 did i say rids? oops, what about "S-1-1" the "Everyone" group
37 and other such well-known sids...
39 speed is not of the essence: no particular optimisation is in place.
47 extern int DEBUGLEVEL
;
49 extern fstring global_sam_name
;
50 extern DOM_SID global_sam_sid
;
51 extern DOM_SID global_sid_S_1_5_20
;
54 * A list of the rids of well known BUILTIN and Domain users
58 rid_name builtin_alias_rids
[] =
60 { BUILTIN_ALIAS_RID_ADMINS
, "Administrators" },
61 { BUILTIN_ALIAS_RID_USERS
, "Users" },
62 { BUILTIN_ALIAS_RID_GUESTS
, "Guests" },
63 { BUILTIN_ALIAS_RID_POWER_USERS
, "Power Users" },
65 { BUILTIN_ALIAS_RID_ACCOUNT_OPS
, "Account Operators" },
66 { BUILTIN_ALIAS_RID_SYSTEM_OPS
, "System Operators" },
67 { BUILTIN_ALIAS_RID_PRINT_OPS
, "Print Operators" },
68 { BUILTIN_ALIAS_RID_BACKUP_OPS
, "Backup Operators" },
69 { BUILTIN_ALIAS_RID_REPLICATOR
, "Replicator" },
73 /* array lookup of well-known Domain RID users. */
74 rid_name domain_user_rids
[] =
76 { DOMAIN_USER_RID_ADMIN
, "Administrator" },
77 { DOMAIN_USER_RID_GUEST
, "Guest" },
81 /* array lookup of well-known Domain RID groups. */
82 rid_name domain_group_rids
[] =
84 { DOMAIN_GROUP_RID_ADMINS
, "Domain Admins" },
85 { DOMAIN_GROUP_RID_USERS
, "Domain Users" },
86 { DOMAIN_GROUP_RID_GUESTS
, "Domain Guests" },
91 int make_dom_gids(DOMAIN_GRP
*mem
, int num_members
, DOM_GID
**ppgids
)
99 DEBUG(4,("make_dom_gids: %d\n", num_members
));
101 if (mem
== NULL
|| num_members
== 0)
106 for (i
= 0, count
= 0; i
< num_members
&& count
< LSA_MAX_GROUPS
; i
++)
113 uint8 attr
= mem
[count
].attr
;
114 char *name
= mem
[count
].name
;
117 status
= lookup_grp_rid(name
, &rid
, &type
);
122 gids
= (DOM_GID
*)Realloc( gids
, sizeof(DOM_GID
) * (count
+1) );
126 DEBUG(0,("make_dom_gids: Realloc fail !\n"));
130 gids
[count
].g_rid
= rid
;
131 gids
[count
].attr
= attr
;
133 DEBUG(5,("group name: %s rid: %d attr: %d\n",
139 DEBUG(1,("make_dom_gids: unknown group name %s\n", name
));
147 /*******************************************************************
148 gets a domain user's groups
149 ********************************************************************/
150 int get_domain_user_groups(DOMAIN_GRP_MEMBER
**grp_members
, uint32 group_rid
)
155 if (grp_members
== NULL
) return 0;
157 grp
= getgrouprid(group_rid
, grp_members
, &num_mem
);
168 /*******************************************************************
170 ********************************************************************/
171 uint32
lookup_builtin_names(uint32 rid
, char *name
, uint8
*type
)
173 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
175 status
= (status
!= 0x0) ? lookup_wk_user_name (rid
, name
, type
) : status
;
176 status
= (status
!= 0x0) ? lookup_wk_group_name(rid
, name
, type
) : status
;
177 status
= (status
!= 0x0) ? lookup_wk_alias_name(rid
, name
, type
) : status
;
183 /*******************************************************************
184 lookup_added_name - names that have been added to the SAM database by admins.
185 ********************************************************************/
186 uint32
lookup_added_name(uint32 rid
, char *name
, uint8
*type
)
188 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
190 status
= (status
!= 0x0) ? lookup_user_name (rid
, name
, type
) : status
;
191 status
= (status
!= 0x0) ? lookup_group_name(rid
, name
, type
) : status
;
192 status
= (status
!= 0x0) ? lookup_alias_name(rid
, name
, type
) : status
;
198 /*******************************************************************
200 ********************************************************************/
201 uint32
lookup_name(uint32 rid
, char *name
, uint8
*type
)
203 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
205 status
= (status
!= 0x0) ? lookup_builtin_names(rid
, name
, type
) : status
;
206 status
= (status
!= 0x0) ? lookup_added_name (rid
, name
, type
) : status
;
212 /*******************************************************************
214 ********************************************************************/
215 uint32
lookup_wk_group_name(uint32 rid
, char *group_name
, uint8
*type
)
218 (*type
) = SID_NAME_WKN_GRP
;
220 DEBUG(5,("lookup_wk_group_name: rid: %d", rid
));
222 while (domain_group_rids
[i
].rid
!= rid
&& domain_group_rids
[i
].rid
!= 0)
227 if (domain_group_rids
[i
].rid
!= 0)
229 fstrcpy(group_name
, domain_group_rids
[i
].name
);
230 DEBUG(5,(" = %s\n", group_name
));
234 DEBUG(5,(" none mapped\n"));
235 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
238 /*******************************************************************
240 ********************************************************************/
241 uint32
lookup_group_name(uint32 rid
, char *group_name
, uint8
*type
)
243 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
246 DEBUG(5,("lookup_group_name: rid: 0x%x", rid
));
248 sid_copy (&sid
, &global_sam_sid
);
249 sid_append_rid(&sid
, rid
);
251 (*type
) = SID_NAME_DOM_GRP
;
253 if (map_group_sid_to_name(&sid
, group_name
, NULL
))
260 DEBUG(5,(" = %s\n", group_name
));
264 DEBUG(5,(" none mapped\n"));
270 /*******************************************************************
272 ********************************************************************/
273 uint32
lookup_wk_alias_name(uint32 rid
, char *alias_name
, uint8
*type
)
276 (*type
) = SID_NAME_ALIAS
;
278 DEBUG(5,("lookup_wk_alias_name: rid: %d", rid
));
280 while (builtin_alias_rids
[i
].rid
!= rid
&& builtin_alias_rids
[i
].rid
!= 0)
285 if (builtin_alias_rids
[i
].rid
!= 0)
287 fstrcpy(alias_name
, builtin_alias_rids
[i
].name
);
288 DEBUG(5,(" = %s\n", alias_name
));
292 DEBUG(5,(" none mapped\n"));
293 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
296 /*******************************************************************
298 ********************************************************************/
299 uint32
lookup_alias_name(uint32 rid
, char *alias_name
, uint8
*type
)
301 (*type
) = SID_NAME_ALIAS
;
303 DEBUG(2,("lookup_alias_name: rid: %d\n", rid
));
304 DEBUG(2,(" NOT IMPLEMENTED\n"));
306 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
309 /*******************************************************************
310 lookup well-known user name
311 ********************************************************************/
312 uint32
lookup_wk_user_name(uint32 rid
, char *user_name
, uint8
*type
)
315 (*type
) = SID_NAME_USER
;
317 DEBUG(5,("lookup_wk_user_name: rid: %d", rid
));
319 /* look up the well-known domain user rids first */
320 while (domain_user_rids
[i
].rid
!= rid
&& domain_user_rids
[i
].rid
!= 0)
325 if (domain_user_rids
[i
].rid
!= 0)
327 fstrcpy(user_name
, domain_user_rids
[i
].name
);
328 DEBUG(5,(" = %s\n", user_name
));
332 DEBUG(5,(" none mapped\n"));
333 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
336 /*******************************************************************
338 ********************************************************************/
339 uint32
lookup_user_name(uint32 rid
, char *user_name
, uint8
*type
)
341 struct sam_disp_info
*disp_info
;
342 (*type
) = SID_NAME_USER
;
344 DEBUG(5,("lookup_user_name: rid: %d", rid
));
346 /* find the user account */
348 disp_info
= getsamdisprid(rid
);
351 if (disp_info
!= NULL
)
353 fstrcpy(user_name
, disp_info
->smb_name
);
354 DEBUG(5,(" = %s\n", user_name
));
358 DEBUG(5,(" none mapped\n"));
359 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
362 /*******************************************************************
364 ********************************************************************/
365 uint32
lookup_group_rid(char *group_name
, uint32
*rid
, uint8
*type
)
370 (*type
) = SID_NAME_DOM_GRP
;
372 DEBUG(5,("lookup_group_rid: name: %s", group_name
));
374 if (map_group_name_to_sid(group_name
, &sid
) &&
375 sid_split_rid(&sid
, rid
) &&
376 sid_equal(&sid
, &global_sam_sid
))
378 DEBUG(5,(" = 0x%x\n", (*rid
)));
382 DEBUG(5,(" none mapped\n"));
383 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
386 /*******************************************************************
388 ********************************************************************/
389 uint32
lookup_wk_group_rid(char *group_name
, uint32
*rid
, uint8
*type
)
392 int i
= -1; /* start do loop at -1 */
394 (*type
) = SID_NAME_WKN_GRP
;
396 do /* find, if it exists, a group rid for the group name */
399 (*rid
) = domain_group_rids
[i
].rid
;
400 grp_name
= domain_group_rids
[i
].name
;
402 } while (grp_name
!= NULL
&& !strequal(grp_name
, group_name
));
404 return (grp_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
407 /*******************************************************************
409 ********************************************************************/
410 uint32
lookup_alias_sid(char *alias_name
, DOM_SID
*sid
, uint8
*type
)
412 (*type
) = SID_NAME_ALIAS
;
414 DEBUG(5,("lookup_alias_rid: name: %s", alias_name
));
416 if (map_alias_name_to_sid(alias_name
, sid
))
419 sid_to_string(sid_str
, sid
);
420 DEBUG(5,(" = %s\n", sid_str
));
424 DEBUG(5,(" none mapped\n"));
425 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
428 /*******************************************************************
430 ********************************************************************/
431 uint32
lookup_alias_rid(char *alias_name
, uint32
*rid
, uint8
*type
)
436 (*type
) = SID_NAME_ALIAS
;
438 DEBUG(5,("lookup_alias_rid: name: %s", alias_name
));
440 if (map_alias_name_to_sid(alias_name
, &sid
) &&
441 sid_split_rid(&sid
, rid
) &&
442 sid_equal(&sid
, &global_sam_sid
))
444 DEBUG(5,(" = 0x%x\n", (*rid
)));
448 DEBUG(5,(" none mapped\n"));
449 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
452 /*******************************************************************
454 ********************************************************************/
455 uint32
lookup_wk_alias_sid(char *alias_name
, DOM_SID
*sid
, uint8
*type
)
460 (*type
) = SID_NAME_ALIAS
;
462 do /* find, if it exists, a alias rid for the alias name*/
464 rid
= builtin_alias_rids
[i
].rid
;
465 als_name
= builtin_alias_rids
[i
].name
;
469 if (strequal(als_name
, alias_name
))
471 sid_copy(sid
, &global_sid_S_1_5_20
);
472 sid_append_rid(sid
, rid
);
477 } while (als_name
!= NULL
);
479 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
482 /*******************************************************************
484 ********************************************************************/
485 uint32
lookup_wk_alias_rid(char *alias_name
, uint32
*rid
, uint8
*type
)
488 int i
= -1; /* start do loop at -1 */
490 (*type
) = SID_NAME_ALIAS
;
492 do /* find, if it exists, a alias rid for the alias name*/
495 (*rid
) = builtin_alias_rids
[i
].rid
;
496 als_name
= builtin_alias_rids
[i
].name
;
498 } while (als_name
!= NULL
&& !strequal(als_name
, alias_name
));
500 return (als_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
503 /*******************************************************************
505 ********************************************************************/
506 uint32
lookup_sid(char *name
, DOM_SID
*sid
, uint8
*type
)
508 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
512 split_domain_name(name
, domain
, user
);
514 if (!strequal(domain
, global_sam_name
))
516 DEBUG(0,("lookup_sid: remote domain %s not supported\n", domain
));
520 status
= (status
!= 0x0) ? lookup_wk_alias_sid(user
, sid
, type
) : status
;
521 status
= (status
!= 0x0) ? lookup_alias_sid (user
, sid
, type
) : status
;
523 status
= (status
!= 0x0) ? lookup_domain_sid (user
, sid
, type
) : status
;
529 /*******************************************************************
530 lookup_added_user_rid
531 ********************************************************************/
532 uint32
lookup_added_user_rids(char *user_name
,
533 uint32
*usr_rid
, uint32
*grp_rid
)
535 SAM_ACCOUNT
*sam_pass
;
539 /* find the user account */
541 sam_pass
= getsampwnam(user_name
);
544 if (sam_pass
!= NULL
)
546 (*usr_rid
) = pdb_get_user_rid(sam_pass
);
547 (*grp_rid
) = pdb_get_group_rid(sam_pass
);
551 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
554 /*******************************************************************
555 lookup_added_user_rid
556 ********************************************************************/
557 uint32
lookup_added_user_rid(char *user_name
, uint32
*rid
, uint8
*type
)
559 SAM_ACCOUNT
*sam_pass
;
561 (*type
) = SID_NAME_USER
;
563 /* find the user account */
565 sam_pass
= getsampwnam(user_name
);
568 if (sam_pass
!= NULL
)
570 (*rid
) = pdb_get_user_rid(sam_pass
);
574 return 0xC0000000 | NT_STATUS_NONE_MAPPED
;
577 /*******************************************************************
579 ********************************************************************/
580 uint32
lookup_wk_user_rid(char *user_name
, uint32
*rid
, uint8
*type
)
583 int i
= -1; /* start do loop at -1 */
585 (*type
) = SID_NAME_USER
;
587 do /* find, if it exists, a alias rid for the alias name*/
590 (*rid
) = domain_user_rids
[i
].rid
;
591 usr_name
= domain_user_rids
[i
].name
;
593 } while (usr_name
!= NULL
&& !strequal(usr_name
, user_name
));
595 return (usr_name
!= NULL
) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED
;
598 /*******************************************************************
600 ********************************************************************/
601 uint32
lookup_added_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
603 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
605 status
= (status
!= 0x0) ? lookup_group_rid(name
, rid
, type
) : status
;
606 status
= (status
!= 0x0) ? lookup_alias_rid(name
, rid
, type
) : status
;
611 /*******************************************************************
612 lookup_builtin_grp_rid
613 ********************************************************************/
614 uint32
lookup_builtin_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
616 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
618 status
= (status
!= 0x0) ? lookup_wk_group_rid(name
, rid
, type
) : status
;
619 status
= (status
!= 0x0) ? lookup_wk_alias_rid(name
, rid
, type
) : status
;
624 /*******************************************************************
626 ********************************************************************/
627 uint32
lookup_grp_rid(char *name
, uint32
*rid
, uint8
*type
)
629 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
631 status
= (status
!= 0x0) ? lookup_builtin_grp_rid(name
, rid
, type
) : status
;
632 status
= (status
!= 0x0) ? lookup_added_grp_rid (name
, rid
, type
) : status
;
637 /*******************************************************************
639 ********************************************************************/
640 uint32
lookup_user_rid(char *name
, uint32
*rid
, uint8
*type
)
642 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
644 status
= (status
!= 0x0) ? lookup_wk_user_rid (name
, rid
, type
) : status
;
645 status
= (status
!= 0x0) ? lookup_added_user_rid(name
, rid
, type
) : status
;
650 /*******************************************************************
652 ********************************************************************/
653 uint32
lookup_rid(char *name
, uint32
*rid
, uint8
*type
)
655 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
657 status
= (status
!= 0x0) ? lookup_user_rid(name
, rid
, type
) : status
;
658 status
= (status
!= 0x0) ? lookup_grp_rid (name
, rid
, type
) : status
;
663 /*******************************************************************
665 ********************************************************************/
666 uint32
lookup_user_rids(char *name
, uint32
*usr_rid
, uint32
*grp_rid
)
668 uint32 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;
672 * try an ordinary user lookup
675 status
= lookup_added_user_rids(name
, usr_rid
, grp_rid
);
682 * hm. must be a well-known user, in a well-known group.
685 status
= lookup_wk_user_rid(name
, usr_rid
, &type
);
686 if (status
!= 0 || type
!= SID_NAME_USER
)
688 return status
; /* ok, maybe not! */
690 if (type
!= SID_NAME_USER
)
692 return 0xC0000000 | NT_STATUS_NONE_MAPPED
; /* users only... */
696 * ok, got the user rid: now try the group rid
699 status
= lookup_builtin_grp_rid(name
, grp_rid
, &type
);
700 if (type
== SID_NAME_DOM_GRP
||
701 type
== SID_NAME_ALIAS
||
702 type
== SID_NAME_WKN_GRP
)
704 status
= 0xC0000000 | NT_STATUS_NONE_MAPPED
;