PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/release/src/router/samba3/source/utils/profiles.c

https://gitlab.com/envieidoc/tomato
C | 286 lines | 201 code | 49 blank | 36 comment | 27 complexity | 509eeb1a4d669eb64b51c12086c2d2bc MD5 | raw file
  1. /*
  2. Samba Unix/Linux SMB client utility profiles.c
  3. Copyright (C) Richard Sharpe, <rsharpe@richardsharpe.com> 2002
  4. Copyright (C) Jelmer Vernooij (conversion to popt) 2003
  5. Copyright (C) Gerald (Jerry) Carter 2005
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include "includes.h"
  19. #include "regfio.h"
  20. /* GLOBAL VARIABLES */
  21. DOM_SID old_sid, new_sid;
  22. int change = 0, new_val = 0;
  23. BOOL opt_verbose = False;
  24. /********************************************************************
  25. ********************************************************************/
  26. static void verbose_output(const char *format, ...) PRINTF_ATTRIBUTE(1,2);
  27. static void verbose_output(const char *format, ...)
  28. {
  29. va_list args;
  30. char *var = NULL;
  31. if (!opt_verbose) {
  32. return;
  33. }
  34. va_start(args, format);
  35. if ((vasprintf(&var, format, args)) == -1) {
  36. va_end(args);
  37. return;
  38. }
  39. fprintf(stdout, var);
  40. va_end(args);
  41. SAFE_FREE(var);
  42. }
  43. /********************************************************************
  44. ********************************************************************/
  45. static BOOL swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 )
  46. {
  47. SEC_ACL *acl;
  48. int i;
  49. BOOL update = False;
  50. verbose_output(" Owner SID: %s\n", sid_string_static(sd->owner_sid));
  51. if ( sid_equal( sd->owner_sid, s1 ) ) {
  52. sid_copy( sd->owner_sid, s2 );
  53. update = True;
  54. verbose_output(" New Owner SID: %s\n",
  55. sid_string_static(sd->owner_sid));
  56. }
  57. verbose_output(" Group SID: %s\n", sid_string_static(sd->group_sid));
  58. if ( sid_equal( sd->group_sid, s1 ) ) {
  59. sid_copy( sd->group_sid, s2 );
  60. update = True;
  61. verbose_output(" New Group SID: %s\n",
  62. sid_string_static(sd->group_sid));
  63. }
  64. acl = sd->dacl;
  65. verbose_output(" DACL: %d entries:\n", acl->num_aces);
  66. for ( i=0; i<acl->num_aces; i++ ) {
  67. verbose_output(" Trustee SID: %s\n",
  68. sid_string_static(&acl->aces[i].trustee));
  69. if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
  70. sid_copy( &acl->aces[i].trustee, s2 );
  71. update = True;
  72. verbose_output(" New Trustee SID: %s\n",
  73. sid_string_static(&acl->aces[i].trustee));
  74. }
  75. }
  76. #if 0
  77. acl = sd->sacl;
  78. verbose_output(" SACL: %d entries: \n", acl->num_aces);
  79. for ( i=0; i<acl->num_aces; i++ ) {
  80. verbose_output(" Trustee SID: %s\n",
  81. sid_string_static(&acl->aces[i].trustee));
  82. if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
  83. sid_copy( &acl->aces[i].trustee, s2 );
  84. update = True;
  85. verbose_output(" New Trustee SID: %s\n",
  86. sid_string_static(&acl->aces[i].trustee));
  87. }
  88. }
  89. #endif
  90. return update;
  91. }
  92. /********************************************************************
  93. ********************************************************************/
  94. static BOOL copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
  95. REGF_NK_REC *parent, REGF_FILE *outfile,
  96. const char *parentpath )
  97. {
  98. REGF_NK_REC *key, *subkey;
  99. SEC_DESC *new_sd;
  100. REGVAL_CTR *values;
  101. REGSUBKEY_CTR *subkeys;
  102. int i;
  103. pstring path;
  104. /* swap out the SIDs in the security descriptor */
  105. if ( !(new_sd = dup_sec_desc( outfile->mem_ctx, nk->sec_desc->sec_desc )) ) {
  106. fprintf( stderr, "Failed to copy security descriptor!\n" );
  107. return False;
  108. }
  109. verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname);
  110. swap_sid_in_acl( new_sd, &old_sid, &new_sid );
  111. if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
  112. DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
  113. return False;
  114. }
  115. if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
  116. DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
  117. return False;
  118. }
  119. /* copy values into the REGVAL_CTR */
  120. for ( i=0; i<nk->num_values; i++ ) {
  121. regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
  122. (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
  123. }
  124. /* copy subkeys into the REGSUBKEY_CTR */
  125. while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
  126. regsubkey_ctr_addkey( subkeys, subkey->keyname );
  127. }
  128. key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent );
  129. /* write each one of the subkeys out */
  130. pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
  131. nk->subkey_index = 0;
  132. while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
  133. if ( !copy_registry_tree( infile, subkey, key, outfile, path ) )
  134. return False;
  135. }
  136. /* values is a talloc()'d child of subkeys here so just throw it all away */
  137. TALLOC_FREE( subkeys );
  138. verbose_output("[%s]\n", path);
  139. return True;
  140. }
  141. /*********************************************************************
  142. *********************************************************************/
  143. int main( int argc, char *argv[] )
  144. {
  145. int opt;
  146. REGF_FILE *infile, *outfile;
  147. REGF_NK_REC *nk;
  148. pstring orig_filename, new_filename;
  149. struct poptOption long_options[] = {
  150. POPT_AUTOHELP
  151. { "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" },
  152. { "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" },
  153. { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 'v', "Verbose output" },
  154. POPT_COMMON_SAMBA
  155. POPT_COMMON_VERSION
  156. POPT_TABLEEND
  157. };
  158. poptContext pc;
  159. load_case_tables();
  160. /* setup logging options */
  161. setup_logging( "profiles", True );
  162. dbf = x_stderr;
  163. x_setbuf( x_stderr, NULL );
  164. pc = poptGetContext("profiles", argc, (const char **)argv, long_options,
  165. POPT_CONTEXT_KEEP_FIRST);
  166. poptSetOtherOptionHelp(pc, "<profilefile>");
  167. /* Now, process the arguments */
  168. while ((opt = poptGetNextOpt(pc)) != -1) {
  169. switch (opt) {
  170. case 'c':
  171. change = 1;
  172. if (!string_to_sid(&old_sid, poptGetOptArg(pc))) {
  173. fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n");
  174. poptPrintUsage(pc, stderr, 0);
  175. exit(254);
  176. }
  177. break;
  178. case 'n':
  179. new_val = 1;
  180. if (!string_to_sid(&new_sid, poptGetOptArg(pc))) {
  181. fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n");
  182. poptPrintUsage(pc, stderr, 0);
  183. exit(253);
  184. }
  185. break;
  186. }
  187. }
  188. poptGetArg(pc);
  189. if (!poptPeekArg(pc)) {
  190. poptPrintUsage(pc, stderr, 0);
  191. exit(1);
  192. }
  193. if ((!change && new_val) || (change && !new_val)) {
  194. fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n");
  195. poptPrintUsage(pc, stderr, 0);
  196. exit(252);
  197. }
  198. pstrcpy( orig_filename, poptPeekArg(pc) );
  199. pstr_sprintf( new_filename, "%s.new", orig_filename );
  200. if ( !(infile = regfio_open( orig_filename, O_RDONLY, 0 )) ) {
  201. fprintf( stderr, "Failed to open %s!\n", orig_filename );
  202. fprintf( stderr, "Error was (%s)\n", strerror(errno) );
  203. exit (1);
  204. }
  205. if ( !(outfile = regfio_open( new_filename, (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
  206. fprintf( stderr, "Failed to open new file %s!\n", new_filename );
  207. fprintf( stderr, "Error was (%s)\n", strerror(errno) );
  208. exit (1);
  209. }
  210. /* actually do the update now */
  211. if ((nk = regfio_rootkey( infile )) == NULL) {
  212. fprintf(stderr, "Could not get rootkey\n");
  213. exit(3);
  214. }
  215. if ( !copy_registry_tree( infile, nk, NULL, outfile, "" ) ) {
  216. fprintf(stderr, "Failed to write updated registry file!\n");
  217. exit(2);
  218. }
  219. /* cleanup */
  220. regfio_close( infile );
  221. regfio_close( outfile );
  222. poptFreeContext(pc);
  223. return( 0 );
  224. }