2 * Unix SMB/CIFS implementation.
3 * Authentication utility functions
4 * Copyright (C) Andrew Tridgell 1992-1998
5 * Copyright (C) Andrew Bartlett 2001
6 * Copyright (C) Jeremy Allison 2000-2001
7 * Copyright (C) Rafal Szczesniak 2002
8 * Copyright (C) Volker Lendecke 2006
9 * Copyright (C) Michael Adam 2007
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.
26 /* functions moved from auth/auth_util.c to minimize linker deps */
30 /****************************************************************************
31 Duplicate a SID token.
32 ****************************************************************************/
34 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken)
41 token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
43 DEBUG(0, ("talloc failed\n"));
49 if (ptoken->user_sids && ptoken->num_sids) {
50 token->user_sids = (DOM_SID *)talloc_memdup(
51 token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
53 if (token->user_sids == NULL) {
54 DEBUG(0, ("talloc_memdup failed\n"));
58 token->num_sids = ptoken->num_sids;
61 /* copy the privileges; don't consider failure to be critical here */
63 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
64 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. "
65 "Continuing with 0 privileges assigned.\n"));
71 /****************************************************************************
72 Check for a SID in an NT_USER_TOKEN
73 ****************************************************************************/
75 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
82 for ( i=0; i<token->num_sids; i++ ) {
83 if ( sid_equal( sid, &token->user_sids[i] ) )
90 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
94 /* if we are a domain member, the get the domain SID, else for
95 a DC or standalone server, use our own SID */
97 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
98 if ( !secrets_fetch_domain_sid( lp_workgroup(),
100 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
101 "SID for domain [%s]\n", lp_workgroup()));
106 sid_copy( &domain_sid, get_global_sam_sid() );
108 sid_append_rid( &domain_sid, rid );
110 return nt_token_check_sid( &domain_sid, token );\
113 /******************************************************************************
114 Create a token for the root user to be used internally by smbd.
115 This is similar to running under the context of the LOCAL_SYSTEM account
116 in Windows. This is a read-only token. Do not modify it or free() it.
117 Create a copy if your need to change it.
118 ******************************************************************************/
120 NT_USER_TOKEN *get_root_nt_token( void )
122 static NT_USER_TOKEN *token = NULL;
123 DOM_SID u_sid, g_sid;
129 if ( !(pw = sys_getpwnam( "root" )) ) {
130 DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
134 /* get the user and primary group SIDs; although the
135 BUILTIN\Administrators SId is really the one that matters here */
137 uid_to_sid(&u_sid, pw->pw_uid);
138 gid_to_sid(&g_sid, pw->pw_gid);
140 token = create_local_nt_token(NULL, &u_sid, False,
141 1, &global_sid_Builtin_Administrators);
147 * Add alias SIDs from memberships within the partially created token SID list
150 NTSTATUS add_aliases(const DOM_SID *domain_sid,
151 struct nt_user_token *token)
154 size_t i, num_aliases;
158 if (!(tmp_ctx = talloc_init("add_aliases"))) {
159 return NT_STATUS_NO_MEMORY;
165 status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
168 &aliases, &num_aliases);
170 if (!NT_STATUS_IS_OK(status)) {
171 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
173 TALLOC_FREE(tmp_ctx);
177 for (i=0; i<num_aliases; i++) {
179 sid_compose(&alias_sid, domain_sid, aliases[i]);
180 if (!add_sid_to_array_unique(token, &alias_sid,
183 DEBUG(0, ("add_sid_to_array failed\n"));
184 TALLOC_FREE(tmp_ctx);
185 return NT_STATUS_NO_MEMORY;
189 TALLOC_FREE(tmp_ctx);
193 /*******************************************************************
194 *******************************************************************/
196 static NTSTATUS add_builtin_administrators( struct nt_user_token *token )
200 /* nothing to do if we aren't in a domain */
202 if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
206 /* Find the Domain Admins SID */
209 sid_copy( &domadm, get_global_sam_sid() );
211 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
212 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
214 sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
216 /* Add Administrators if the user beloongs to Domain Admins */
218 if ( nt_token_check_sid( &domadm, token ) ) {
219 if (!add_sid_to_array(token, &global_sid_Builtin_Administrators,
220 &token->user_sids, &token->num_sids)) {
221 return NT_STATUS_NO_MEMORY;
228 /*******************************************************************
229 *******************************************************************/
231 static NTSTATUS create_builtin_users( void )
236 status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
237 if ( !NT_STATUS_IS_OK(status) ) {
238 DEBUG(0,("create_builtin_users: Failed to create Users\n"));
242 /* add domain users */
243 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
244 && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
246 sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
247 status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
248 if ( !NT_STATUS_IS_OK(status) ) {
249 DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
258 /*******************************************************************
259 *******************************************************************/
261 static NTSTATUS create_builtin_administrators( void )
264 DOM_SID dom_admins, root_sid;
266 enum lsa_SidType type;
270 status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
271 if ( !NT_STATUS_IS_OK(status) ) {
272 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
276 /* add domain admins */
277 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
278 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
280 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
281 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
282 if ( !NT_STATUS_IS_OK(status) ) {
283 DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
284 " Administrators\n"));
290 if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
291 return NT_STATUS_NO_MEMORY;
293 fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
294 ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
298 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
299 if ( !NT_STATUS_IS_OK(status) ) {
300 DEBUG(0,("create_builtin_administrators: Failed to add root"
301 " Administrators\n"));
310 /*******************************************************************
311 Create a NT token for the user, expanding local aliases
312 *******************************************************************/
314 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
315 const DOM_SID *user_sid,
318 const DOM_SID *groupsids)
320 struct nt_user_token *result = NULL;
325 DEBUG(10, ("Create local NT token for %s\n", sid_string_static(user_sid)));
327 if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
328 DEBUG(0, ("talloc failed\n"));
332 /* Add the user and primary group sid */
334 if (!add_sid_to_array(result, user_sid,
335 &result->user_sids, &result->num_sids)) {
339 /* For guest, num_groupsids may be zero. */
341 if (!add_sid_to_array(result, &groupsids[0],
342 &result->user_sids, &result->num_sids)) {
347 /* Add in BUILTIN sids */
349 if (!add_sid_to_array(result, &global_sid_World,
350 &result->user_sids, &result->num_sids)) {
353 if (!add_sid_to_array(result, &global_sid_Network,
354 &result->user_sids, &result->num_sids)) {
359 if (!add_sid_to_array(result, &global_sid_Builtin_Guests,
360 &result->user_sids, &result->num_sids)) {
364 if (!add_sid_to_array(result, &global_sid_Authenticated_Users,
365 &result->user_sids, &result->num_sids)) {
370 /* Now the SIDs we got from authentication. These are the ones from
371 * the info3 struct or from the pdb_enum_group_memberships, depending
372 * on who authenticated the user.
373 * Note that we start the for loop at "1" here, we already added the
374 * first group sid as primary above. */
376 for (i=1; i<num_groupsids; i++) {
377 if (!add_sid_to_array_unique(result, &groupsids[i],
378 &result->user_sids, &result->num_sids)) {
383 /* Deal with the BUILTIN\Administrators group. If the SID can
384 be resolved then assume that the add_aliasmem( S-1-5-32 )
387 if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
388 /* We can only create a mapping if winbind is running
389 and the nested group functionality has been enabled */
391 if ( lp_winbind_nested_groups() && winbind_ping() ) {
393 status = create_builtin_administrators( );
394 if ( !NT_STATUS_IS_OK(status) ) {
395 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
396 /* don't fail, just log the message */
401 status = add_builtin_administrators( result );
402 if ( !NT_STATUS_IS_OK(status) ) {
403 /* just log a complaint but do not fail */
404 DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
405 " membership (%s)\n", nt_errstr(status)));
410 /* Deal with the BUILTIN\Users group. If the SID can
411 be resolved then assume that the add_aliasmem( S-1-5-32 )
414 if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
415 /* We can only create a mapping if winbind is running
416 and the nested group functionality has been enabled */
418 if ( lp_winbind_nested_groups() && winbind_ping() ) {
420 status = create_builtin_users( );
421 if ( !NT_STATUS_IS_OK(status) ) {
422 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Users group!\n"));
423 /* don't fail, just log the message */
429 /* Deal with local groups */
431 if (lp_winbind_nested_groups()) {
433 /* Now add the aliases. First the one from our local SAM */
435 status = add_aliases(get_global_sam_sid(), result);
437 if (!NT_STATUS_IS_OK(status)) {
442 /* Finally the builtin ones */
444 status = add_aliases(&global_sid_Builtin, result);
446 if (!NT_STATUS_IS_OK(status)) {
453 get_privileges_for_sids(&result->privileges, result->user_sids,
458 /****************************************************************************
459 prints a NT_USER_TOKEN to debug output.
460 ****************************************************************************/
462 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
467 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
471 DEBUGC(dbg_class, dbg_lev,
472 ("NT user token of user %s\n",
473 sid_string_static(&token->user_sids[0]) ));
474 DEBUGADDC(dbg_class, dbg_lev,
475 ("contains %lu SIDs\n", (unsigned long)token->num_sids));
476 for (i = 0; i < token->num_sids; i++)
477 DEBUGADDC(dbg_class, dbg_lev,
478 ("SID[%3lu]: %s\n", (unsigned long)i,
479 sid_string_static(&token->user_sids[i])));
481 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
484 /****************************************************************************
485 prints a UNIX 'token' to debug output.
486 ****************************************************************************/
488 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
489 int n_groups, gid_t *groups)
492 DEBUGC(dbg_class, dbg_lev,
493 ("UNIX token of user %ld\n", (long int)uid));
495 DEBUGADDC(dbg_class, dbg_lev,
496 ("Primary group is %ld and contains %i supplementary "
497 "groups\n", (long int)gid, n_groups));
498 for (i = 0; i < n_groups; i++)
499 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
500 (long int)groups[i]));