PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/samba-3.5.6/source3/auth/token_util.c

https://github.com/theuni/XBMC-deps
C | 561 lines | 363 code | 104 blank | 94 comment | 72 complexity | e3a87e1cdc70b82f6e9ac16d5eeaf877 MD5 | raw file
  1. /*
  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
  10. *
  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 3 of the License, or
  14. * (at your option) any later version.
  15. *
  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.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  23. */
  24. /* functions moved from auth/auth_util.c to minimize linker deps */
  25. #include "includes.h"
  26. /****************************************************************************
  27. Check for a SID in an NT_USER_TOKEN
  28. ****************************************************************************/
  29. bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
  30. {
  31. int i;
  32. if ( !sid || !token )
  33. return False;
  34. for ( i=0; i<token->num_sids; i++ ) {
  35. if ( sid_equal( sid, &token->user_sids[i] ) )
  36. return True;
  37. }
  38. return False;
  39. }
  40. bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
  41. {
  42. DOM_SID domain_sid;
  43. /* if we are a domain member, the get the domain SID, else for
  44. a DC or standalone server, use our own SID */
  45. if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
  46. if ( !secrets_fetch_domain_sid( lp_workgroup(),
  47. &domain_sid ) ) {
  48. DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
  49. "SID for domain [%s]\n", lp_workgroup()));
  50. return False;
  51. }
  52. }
  53. else
  54. sid_copy( &domain_sid, get_global_sam_sid() );
  55. sid_append_rid( &domain_sid, rid );
  56. return nt_token_check_sid( &domain_sid, token );\
  57. }
  58. /******************************************************************************
  59. Create a token for the root user to be used internally by smbd.
  60. This is similar to running under the context of the LOCAL_SYSTEM account
  61. in Windows. This is a read-only token. Do not modify it or free() it.
  62. Create a copy if your need to change it.
  63. ******************************************************************************/
  64. NT_USER_TOKEN *get_root_nt_token( void )
  65. {
  66. struct nt_user_token *token, *for_cache;
  67. DOM_SID u_sid, g_sid;
  68. struct passwd *pw;
  69. void *cache_data;
  70. cache_data = memcache_lookup_talloc(
  71. NULL, SINGLETON_CACHE_TALLOC,
  72. data_blob_string_const_null("root_nt_token"));
  73. if (cache_data != NULL) {
  74. return talloc_get_type_abort(
  75. cache_data, struct nt_user_token);
  76. }
  77. if ( !(pw = sys_getpwuid(0)) ) {
  78. if ( !(pw = sys_getpwnam("root")) ) {
  79. DEBUG(0,("get_root_nt_token: both sys_getpwuid(0) "
  80. "and sys_getpwnam(\"root\") failed!\n"));
  81. return NULL;
  82. }
  83. }
  84. /* get the user and primary group SIDs; although the
  85. BUILTIN\Administrators SId is really the one that matters here */
  86. uid_to_sid(&u_sid, pw->pw_uid);
  87. gid_to_sid(&g_sid, pw->pw_gid);
  88. token = create_local_nt_token(talloc_autofree_context(), &u_sid, False,
  89. 1, &global_sid_Builtin_Administrators);
  90. token->privileges = se_disk_operators;
  91. for_cache = token;
  92. memcache_add_talloc(
  93. NULL, SINGLETON_CACHE_TALLOC,
  94. data_blob_string_const_null("root_nt_token"), &for_cache);
  95. return token;
  96. }
  97. /*
  98. * Add alias SIDs from memberships within the partially created token SID list
  99. */
  100. NTSTATUS add_aliases(const DOM_SID *domain_sid,
  101. struct nt_user_token *token)
  102. {
  103. uint32 *aliases;
  104. size_t i, num_aliases;
  105. NTSTATUS status;
  106. TALLOC_CTX *tmp_ctx;
  107. if (!(tmp_ctx = talloc_init("add_aliases"))) {
  108. return NT_STATUS_NO_MEMORY;
  109. }
  110. aliases = NULL;
  111. num_aliases = 0;
  112. status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
  113. token->user_sids,
  114. token->num_sids,
  115. &aliases, &num_aliases);
  116. if (!NT_STATUS_IS_OK(status)) {
  117. DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
  118. nt_errstr(status)));
  119. goto done;
  120. }
  121. for (i=0; i<num_aliases; i++) {
  122. DOM_SID alias_sid;
  123. sid_compose(&alias_sid, domain_sid, aliases[i]);
  124. status = add_sid_to_array_unique(token, &alias_sid,
  125. &token->user_sids,
  126. &token->num_sids);
  127. if (!NT_STATUS_IS_OK(status)) {
  128. DEBUG(0, ("add_sid_to_array failed\n"));
  129. goto done;
  130. }
  131. }
  132. done:
  133. TALLOC_FREE(tmp_ctx);
  134. return NT_STATUS_OK;
  135. }
  136. /*******************************************************************
  137. *******************************************************************/
  138. static NTSTATUS add_builtin_administrators(struct nt_user_token *token,
  139. const DOM_SID *dom_sid)
  140. {
  141. DOM_SID domadm;
  142. NTSTATUS status;
  143. /* nothing to do if we aren't in a domain */
  144. if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
  145. return NT_STATUS_OK;
  146. }
  147. /* Find the Domain Admins SID */
  148. if ( IS_DC ) {
  149. sid_copy( &domadm, get_global_sam_sid() );
  150. } else {
  151. sid_copy(&domadm, dom_sid);
  152. }
  153. sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
  154. /* Add Administrators if the user beloongs to Domain Admins */
  155. if ( nt_token_check_sid( &domadm, token ) ) {
  156. status = add_sid_to_array(token,
  157. &global_sid_Builtin_Administrators,
  158. &token->user_sids, &token->num_sids);
  159. if (!NT_STATUS_IS_OK(status)) {
  160. return status;
  161. }
  162. }
  163. return NT_STATUS_OK;
  164. }
  165. /**
  166. * Create the requested BUILTIN if it doesn't already exist. This requires
  167. * winbindd to be running.
  168. *
  169. * @param[in] rid BUILTIN rid to create
  170. * @return Normal NTSTATUS return.
  171. */
  172. static NTSTATUS create_builtin(uint32 rid)
  173. {
  174. NTSTATUS status = NT_STATUS_OK;
  175. DOM_SID sid;
  176. gid_t gid;
  177. if (!sid_compose(&sid, &global_sid_Builtin, rid)) {
  178. return NT_STATUS_NO_SUCH_ALIAS;
  179. }
  180. if (!sid_to_gid(&sid, &gid)) {
  181. if (!lp_winbind_nested_groups() || !winbind_ping()) {
  182. return NT_STATUS_PROTOCOL_UNREACHABLE;
  183. }
  184. status = pdb_create_builtin_alias(rid);
  185. }
  186. return status;
  187. }
  188. /**
  189. * Add sid as a member of builtin_sid.
  190. *
  191. * @param[in] builtin_sid An existing builtin group.
  192. * @param[in] dom_sid sid to add as a member of builtin_sid.
  193. * @return Normal NTSTATUS return
  194. */
  195. static NTSTATUS add_sid_to_builtin(const DOM_SID *builtin_sid,
  196. const DOM_SID *dom_sid)
  197. {
  198. NTSTATUS status = NT_STATUS_OK;
  199. if (!dom_sid || !builtin_sid) {
  200. return NT_STATUS_INVALID_PARAMETER;
  201. }
  202. status = pdb_add_aliasmem(builtin_sid, dom_sid);
  203. if (NT_STATUS_EQUAL(status, NT_STATUS_MEMBER_IN_ALIAS)) {
  204. DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n",
  205. sid_string_dbg(dom_sid),
  206. sid_string_dbg(builtin_sid)));
  207. return NT_STATUS_OK;
  208. }
  209. if (!NT_STATUS_IS_OK(status)) {
  210. DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: "
  211. "%s\n", sid_string_dbg(dom_sid),
  212. sid_string_dbg(builtin_sid), nt_errstr(status)));
  213. }
  214. return status;
  215. }
  216. /*******************************************************************
  217. *******************************************************************/
  218. NTSTATUS create_builtin_users(const DOM_SID *dom_sid)
  219. {
  220. NTSTATUS status;
  221. DOM_SID dom_users;
  222. status = create_builtin(BUILTIN_ALIAS_RID_USERS);
  223. if ( !NT_STATUS_IS_OK(status) ) {
  224. DEBUG(5,("create_builtin_users: Failed to create Users\n"));
  225. return status;
  226. }
  227. /* add domain users */
  228. if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
  229. && sid_compose(&dom_users, dom_sid, DOMAIN_GROUP_RID_USERS))
  230. {
  231. status = add_sid_to_builtin(&global_sid_Builtin_Users,
  232. &dom_users);
  233. }
  234. return status;
  235. }
  236. /*******************************************************************
  237. *******************************************************************/
  238. NTSTATUS create_builtin_administrators(const DOM_SID *dom_sid)
  239. {
  240. NTSTATUS status;
  241. DOM_SID dom_admins, root_sid;
  242. fstring root_name;
  243. enum lsa_SidType type;
  244. TALLOC_CTX *ctx;
  245. bool ret;
  246. status = create_builtin(BUILTIN_ALIAS_RID_ADMINS);
  247. if ( !NT_STATUS_IS_OK(status) ) {
  248. DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n"));
  249. return status;
  250. }
  251. /* add domain admins */
  252. if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
  253. && sid_compose(&dom_admins, dom_sid, DOMAIN_GROUP_RID_ADMINS))
  254. {
  255. status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
  256. &dom_admins);
  257. if (!NT_STATUS_IS_OK(status)) {
  258. return status;
  259. }
  260. }
  261. /* add root */
  262. if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
  263. return NT_STATUS_NO_MEMORY;
  264. }
  265. fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
  266. ret = lookup_name(ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL,
  267. &root_sid, &type);
  268. TALLOC_FREE( ctx );
  269. if ( ret ) {
  270. status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
  271. &root_sid);
  272. }
  273. return status;
  274. }
  275. /*******************************************************************
  276. Create a NT token for the user, expanding local aliases
  277. *******************************************************************/
  278. struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
  279. const DOM_SID *user_sid,
  280. bool is_guest,
  281. int num_groupsids,
  282. const DOM_SID *groupsids)
  283. {
  284. struct nt_user_token *result = NULL;
  285. int i;
  286. NTSTATUS status;
  287. gid_t gid;
  288. DOM_SID dom_sid;
  289. DEBUG(10, ("Create local NT token for %s\n",
  290. sid_string_dbg(user_sid)));
  291. if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) {
  292. DEBUG(0, ("talloc failed\n"));
  293. return NULL;
  294. }
  295. /* Add the user and primary group sid */
  296. status = add_sid_to_array(result, user_sid,
  297. &result->user_sids, &result->num_sids);
  298. if (!NT_STATUS_IS_OK(status)) {
  299. return NULL;
  300. }
  301. /* For guest, num_groupsids may be zero. */
  302. if (num_groupsids) {
  303. status = add_sid_to_array(result, &groupsids[0],
  304. &result->user_sids,
  305. &result->num_sids);
  306. if (!NT_STATUS_IS_OK(status)) {
  307. return NULL;
  308. }
  309. }
  310. /* Add in BUILTIN sids */
  311. status = add_sid_to_array(result, &global_sid_World,
  312. &result->user_sids, &result->num_sids);
  313. if (!NT_STATUS_IS_OK(status)) {
  314. return NULL;
  315. }
  316. status = add_sid_to_array(result, &global_sid_Network,
  317. &result->user_sids, &result->num_sids);
  318. if (!NT_STATUS_IS_OK(status)) {
  319. return NULL;
  320. }
  321. if (is_guest) {
  322. status = add_sid_to_array(result, &global_sid_Builtin_Guests,
  323. &result->user_sids,
  324. &result->num_sids);
  325. if (!NT_STATUS_IS_OK(status)) {
  326. return NULL;
  327. }
  328. } else {
  329. status = add_sid_to_array(result,
  330. &global_sid_Authenticated_Users,
  331. &result->user_sids,
  332. &result->num_sids);
  333. if (!NT_STATUS_IS_OK(status)) {
  334. return NULL;
  335. }
  336. }
  337. /* Now the SIDs we got from authentication. These are the ones from
  338. * the info3 struct or from the pdb_enum_group_memberships, depending
  339. * on who authenticated the user.
  340. * Note that we start the for loop at "1" here, we already added the
  341. * first group sid as primary above. */
  342. for (i=1; i<num_groupsids; i++) {
  343. status = add_sid_to_array_unique(result, &groupsids[i],
  344. &result->user_sids,
  345. &result->num_sids);
  346. if (!NT_STATUS_IS_OK(status)) {
  347. return NULL;
  348. }
  349. }
  350. /* Deal with the BUILTIN\Administrators group. If the SID can
  351. be resolved then assume that the add_aliasmem( S-1-5-32 )
  352. handled it. */
  353. if (!sid_to_gid(&global_sid_Builtin_Administrators, &gid)) {
  354. become_root();
  355. if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
  356. status = NT_STATUS_OK;
  357. DEBUG(3, ("Failed to fetch domain sid for %s\n",
  358. lp_workgroup()));
  359. } else {
  360. status = create_builtin_administrators(&dom_sid);
  361. }
  362. unbecome_root();
  363. if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
  364. /* Add BUILTIN\Administrators directly to token. */
  365. status = add_builtin_administrators(result, &dom_sid);
  366. if ( !NT_STATUS_IS_OK(status) ) {
  367. DEBUG(3, ("Failed to check for local "
  368. "Administrators membership (%s)\n",
  369. nt_errstr(status)));
  370. }
  371. } else if (!NT_STATUS_IS_OK(status)) {
  372. DEBUG(2, ("WARNING: Failed to create "
  373. "BUILTIN\\Administrators group! Can "
  374. "Winbind allocate gids?\n"));
  375. }
  376. }
  377. /* Deal with the BUILTIN\Users group. If the SID can
  378. be resolved then assume that the add_aliasmem( S-1-5-32 )
  379. handled it. */
  380. if (!sid_to_gid(&global_sid_Builtin_Users, &gid)) {
  381. become_root();
  382. if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
  383. status = NT_STATUS_OK;
  384. DEBUG(3, ("Failed to fetch domain sid for %s\n",
  385. lp_workgroup()));
  386. } else {
  387. status = create_builtin_users(&dom_sid);
  388. }
  389. unbecome_root();
  390. if (!NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) &&
  391. !NT_STATUS_IS_OK(status))
  392. {
  393. DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! "
  394. "Can Winbind allocate gids?\n"));
  395. }
  396. }
  397. /* Deal with local groups */
  398. if (lp_winbind_nested_groups()) {
  399. become_root();
  400. /* Now add the aliases. First the one from our local SAM */
  401. status = add_aliases(get_global_sam_sid(), result);
  402. if (!NT_STATUS_IS_OK(status)) {
  403. unbecome_root();
  404. TALLOC_FREE(result);
  405. return NULL;
  406. }
  407. /* Finally the builtin ones */
  408. status = add_aliases(&global_sid_Builtin, result);
  409. if (!NT_STATUS_IS_OK(status)) {
  410. unbecome_root();
  411. TALLOC_FREE(result);
  412. return NULL;
  413. }
  414. unbecome_root();
  415. }
  416. get_privileges_for_sids(&result->privileges, result->user_sids,
  417. result->num_sids);
  418. return result;
  419. }
  420. /****************************************************************************
  421. prints a NT_USER_TOKEN to debug output.
  422. ****************************************************************************/
  423. void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
  424. {
  425. size_t i;
  426. if (!token) {
  427. DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
  428. return;
  429. }
  430. DEBUGC(dbg_class, dbg_lev,
  431. ("NT user token of user %s\n",
  432. sid_string_dbg(&token->user_sids[0]) ));
  433. DEBUGADDC(dbg_class, dbg_lev,
  434. ("contains %lu SIDs\n", (unsigned long)token->num_sids));
  435. for (i = 0; i < token->num_sids; i++)
  436. DEBUGADDC(dbg_class, dbg_lev,
  437. ("SID[%3lu]: %s\n", (unsigned long)i,
  438. sid_string_dbg(&token->user_sids[i])));
  439. dump_se_priv( dbg_class, dbg_lev, &token->privileges );
  440. }
  441. /****************************************************************************
  442. prints a UNIX 'token' to debug output.
  443. ****************************************************************************/
  444. void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
  445. int n_groups, gid_t *groups)
  446. {
  447. int i;
  448. DEBUGC(dbg_class, dbg_lev,
  449. ("UNIX token of user %ld\n", (long int)uid));
  450. DEBUGADDC(dbg_class, dbg_lev,
  451. ("Primary group is %ld and contains %i supplementary "
  452. "groups\n", (long int)gid, n_groups));
  453. for (i = 0; i < n_groups; i++)
  454. DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
  455. (long int)groups[i]));
  456. }
  457. /* END */