root/source3/rpc_server/srv_winreg_nt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_regkey_by_hnd
  2. open_registry_key
  3. close_registry_key
  4. _winreg_CloseKey
  5. _winreg_OpenHKLM
  6. _winreg_OpenHKPD
  7. _winreg_OpenHKPT
  8. _winreg_OpenHKCR
  9. _winreg_OpenHKU
  10. _winreg_OpenHKCU
  11. _winreg_OpenHKCC
  12. _winreg_OpenHKDD
  13. _winreg_OpenHKPN
  14. _winreg_OpenKey
  15. _winreg_QueryValue
  16. _winreg_QueryInfoKey
  17. _winreg_GetVersion
  18. _winreg_EnumKey
  19. _winreg_EnumValue
  20. _winreg_InitiateSystemShutdown
  21. _winreg_InitiateSystemShutdownEx
  22. _winreg_AbortSystemShutdown
  23. validate_reg_filename
  24. _winreg_RestoreKey
  25. _winreg_SaveKey
  26. _winreg_SaveKeyEx
  27. _winreg_CreateKey
  28. _winreg_SetValue
  29. _winreg_DeleteKey
  30. _winreg_DeleteValue
  31. _winreg_GetKeySecurity
  32. _winreg_SetKeySecurity
  33. _winreg_FlushKey
  34. _winreg_UnLoadKey
  35. _winreg_ReplaceKey
  36. _winreg_LoadKey
  37. _winreg_NotifyChangeKeyValue
  38. _winreg_QueryMultipleValues
  39. _winreg_QueryMultipleValues2

   1 /* 
   2  *  Unix SMB/CIFS implementation.
   3  *  RPC Pipe client / server routines
   4  * 
   5  *  Copyright (C) Gerald Carter                 2002-2006.
   6  *
   7  *  This program is free software; you can redistribute it and/or modify
   8  *  it under the terms of the GNU General Public License as published by
   9  *  the Free Software Foundation; either version 3 of the License, or
  10  *  (at your option) any later version.
  11  *  
  12  *  This program is distributed in the hope that it will be useful,
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  *  GNU General Public License for more details.
  16  *  
  17  *  You should have received a copy of the GNU General Public License
  18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 /* Implementation of registry functions. */
  22 
  23 #include "includes.h"
  24 
  25 #undef DBGC_CLASS
  26 #define DBGC_CLASS DBGC_RPC_SRV
  27 
  28 /******************************************************************
  29  Find a registry key handle and return a struct registry_key *
  30  *****************************************************************/
  31 
  32 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
     /* [<][>][^][v][top][bottom][index][help] */
  33                                                struct policy_handle *hnd)
  34 {
  35         struct registry_key *regkey = NULL;
  36 
  37         if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
  38                 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
  39                 return NULL;
  40         }
  41 
  42         return regkey;
  43 }
  44 
  45 /*******************************************************************
  46  Function for open a new registry handle and creating a handle 
  47  Note that P should be valid & hnd should already have space
  48  
  49  When we open a key, we store the full path to the key as 
  50  HK[LM|U]\<key>\<key>\...
  51  *******************************************************************/
  52  
  53 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
     /* [<][>][^][v][top][bottom][index][help] */
  54                                  struct registry_key *parent,
  55                                  const char *subkeyname,
  56                                  uint32 access_desired  )
  57 {
  58         WERROR result = WERR_OK;
  59         struct registry_key *key;
  60 
  61         if (parent == NULL) {
  62                 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
  63                                       p->server_info->ptok, &key);
  64         }
  65         else {
  66                 result = reg_openkey(p->mem_ctx, parent, subkeyname,
  67                                      access_desired, &key);
  68         }
  69 
  70         if ( !W_ERROR_IS_OK(result) ) {
  71                 return result;
  72         }
  73         
  74         if ( !create_policy_hnd( p, hnd, key ) ) {
  75                 return WERR_BADFILE; 
  76         }
  77         
  78         return WERR_OK;
  79 }
  80 
  81 /*******************************************************************
  82  Function for open a new registry handle and creating a handle 
  83  Note that P should be valid & hnd should already have space
  84  *******************************************************************/
  85 
  86 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
     /* [<][>][^][v][top][bottom][index][help] */
  87 {
  88         struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
  89         
  90         if ( !regkey ) {
  91                 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
  92                          OUR_HANDLE(hnd)));
  93                 return False;
  94         }
  95         
  96         close_policy_hnd(p, hnd);
  97         
  98         return True;
  99 }
 100 
 101 /********************************************************************
 102  reg_close
 103  ********************************************************************/
 104 
 105 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 106 {
 107         /* close the policy handle */
 108 
 109         if (!close_registry_key(p, r->in.handle))
 110                 return WERR_BADFID; 
 111 
 112         ZERO_STRUCTP(r->out.handle);
 113 
 114         return WERR_OK;
 115 }
 116 
 117 /*******************************************************************
 118  ********************************************************************/
 119 
 120 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
     /* [<][>][^][v][top][bottom][index][help] */
 121 {
 122         return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
 123 }
 124 
 125 /*******************************************************************
 126  ********************************************************************/
 127 
 128 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
 131 }
 132 
 133 /*******************************************************************
 134  ********************************************************************/
 135 
 136 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
     /* [<][>][^][v][top][bottom][index][help] */
 137 {
 138         return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
 139 }
 140 
 141 /*******************************************************************
 142  ********************************************************************/
 143 
 144 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146         return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
 147 }
 148 
 149 /*******************************************************************
 150  ********************************************************************/
 151 
 152 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
     /* [<][>][^][v][top][bottom][index][help] */
 153 {
 154         return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
 155 }
 156 
 157 /*******************************************************************
 158  ********************************************************************/
 159 
 160 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
     /* [<][>][^][v][top][bottom][index][help] */
 161 {
 162         return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
 163 }
 164 
 165 /*******************************************************************
 166  ********************************************************************/
 167 
 168 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
     /* [<][>][^][v][top][bottom][index][help] */
 169 {
 170         return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
 171 }
 172 
 173 /*******************************************************************
 174  ********************************************************************/
 175 
 176 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178         return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
 179 }
 180 
 181 /*******************************************************************
 182  ********************************************************************/
 183 
 184 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
     /* [<][>][^][v][top][bottom][index][help] */
 185 {
 186         return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
 187 }
 188 
 189 /*******************************************************************
 190  reg_reply_open_entry
 191  ********************************************************************/
 192 
 193 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 194 {
 195         struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
 196 
 197         if ( !parent )
 198                 return WERR_BADFID;
 199 
 200         return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
 201 }
 202 
 203 /*******************************************************************
 204  reg_reply_info
 205  ********************************************************************/
 206 
 207 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
     /* [<][>][^][v][top][bottom][index][help] */
 208 {
 209         WERROR        status = WERR_BADFILE;
 210         struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 211         prs_struct    prs_hkpd;
 212 
 213         uint8_t *outbuf;
 214         uint32_t outbuf_size;
 215 
 216         DATA_BLOB val_blob;
 217         bool free_buf = False;
 218         bool free_prs = False;
 219 
 220         if ( !regkey )
 221                 return WERR_BADFID;
 222 
 223         if ((r->out.data_length == NULL) || (r->out.type == NULL)) {
 224                 return WERR_INVALID_PARAM;
 225         }
 226 
 227         *r->out.data_length = *r->out.type = REG_NONE;
 228         
 229         DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
 230         DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
 231         
 232         /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
 233         if(regkey->key->type == REG_KEY_HKPD) 
 234         {
 235                 if (strequal(r->in.value_name->name, "Global")) {
 236                         if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
 237                                 return WERR_NOMEM;
 238                         status = reg_perfcount_get_hkpd(
 239                                 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
 240                         outbuf = (uint8_t *)prs_hkpd.data_p;
 241                         free_prs = True;
 242                 }
 243                 else if (strequal(r->in.value_name->name, "Counter 009")) {
 244                         outbuf_size = reg_perfcount_get_counter_names(
 245                                 reg_perfcount_get_base_index(),
 246                                 (char **)(void *)&outbuf);
 247                         free_buf = True;
 248                 }
 249                 else if (strequal(r->in.value_name->name, "Explain 009")) {
 250                         outbuf_size = reg_perfcount_get_counter_help(
 251                                 reg_perfcount_get_base_index(),
 252                                 (char **)(void *)&outbuf);
 253                         free_buf = True;
 254                 }
 255                 else if (isdigit(r->in.value_name->name[0])) {
 256                         /* we probably have a request for a specific object
 257                          * here */
 258                         if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
 259                                 return WERR_NOMEM;
 260                         status = reg_perfcount_get_hkpd(
 261                                 &prs_hkpd, *r->in.data_size, &outbuf_size,
 262                                 r->in.value_name->name);
 263                         outbuf = (uint8_t *)prs_hkpd.data_p;
 264                         free_prs = True;
 265                 }
 266                 else {
 267                         DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
 268                                  r->in.value_name->name));
 269                         return WERR_BADFILE;
 270                 }
 271 
 272                 *r->out.type = REG_BINARY;
 273         }
 274         else {
 275                 struct registry_value *val;
 276 
 277                 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
 278                                         &val);
 279                 if (!W_ERROR_IS_OK(status)) {
 280                         if (r->out.data_size) {
 281                                 *r->out.data_size = 0;
 282                         }
 283                         if (r->out.data_length) {
 284                                 *r->out.data_length = 0;
 285                         }
 286                         return status;
 287                 }
 288 
 289                 status = registry_push_value(p->mem_ctx, val, &val_blob);
 290                 if (!W_ERROR_IS_OK(status)) {
 291                         return status;
 292                 }
 293 
 294                 outbuf = val_blob.data;
 295                 outbuf_size = val_blob.length;
 296                 *r->out.type = val->type;
 297         }
 298 
 299         *r->out.data_length = outbuf_size;
 300 
 301         if ( *r->in.data_size == 0 || !r->out.data ) {
 302                 status = WERR_OK;
 303         } else if ( *r->out.data_length > *r->in.data_size ) {
 304                 status = WERR_MORE_DATA;
 305         } else {
 306                 memcpy( r->out.data, outbuf, *r->out.data_length );
 307                 status = WERR_OK;
 308         }
 309 
 310         *r->out.data_size = *r->out.data_length;
 311 
 312         if (free_prs) prs_mem_free(&prs_hkpd);
 313         if (free_buf) SAFE_FREE(outbuf);
 314 
 315         return status;
 316 }
 317 
 318 /*****************************************************************************
 319  Implementation of REG_QUERY_KEY
 320  ****************************************************************************/
 321 
 322 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 323 {
 324         WERROR  status = WERR_OK;
 325         struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 326         
 327         if ( !regkey )
 328                 return WERR_BADFID;
 329 
 330         r->out.classname->name = NULL;
 331 
 332         status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
 333                                   r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
 334                                   r->out.max_valbufsize, r->out.secdescsize,
 335                                   r->out.last_changed_time);
 336         if (!W_ERROR_IS_OK(status)) {
 337                 return status;
 338         }
 339 
 340         /*
 341          * These calculations account for the registry buffers being
 342          * UTF-16. They are inexact at best, but so far they worked.
 343          */
 344 
 345         *r->out.max_subkeylen *= 2;
 346 
 347         *r->out.max_valnamelen += 1;
 348         *r->out.max_valnamelen *= 2;
 349         
 350         return WERR_OK;
 351 }
 352 
 353 
 354 /*****************************************************************************
 355  Implementation of REG_GETVERSION
 356  ****************************************************************************/
 357  
 358 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
     /* [<][>][^][v][top][bottom][index][help] */
 359 {
 360         struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 361         
 362         if ( !regkey )
 363                 return WERR_BADFID;
 364         
 365         return reg_getversion(r->out.version);
 366 }
 367 
 368 
 369 /*****************************************************************************
 370  Implementation of REG_ENUM_KEY
 371  ****************************************************************************/
 372  
 373 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 374 {
 375         WERROR err;
 376         struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
 377         
 378         if ( !key )
 379                 return WERR_BADFID; 
 380 
 381         if ( !r->in.name || !r->in.keyclass )
 382                 return WERR_INVALID_PARAM;
 383 
 384         DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
 385 
 386         err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
 387                           r->out.last_changed_time);
 388         if (!W_ERROR_IS_OK(err)) {
 389                 return err;
 390         }
 391         r->out.keyclass->name = "";
 392         return WERR_OK;
 393 }
 394 
 395 /*****************************************************************************
 396  Implementation of REG_ENUM_VALUE
 397  ****************************************************************************/
 398 
 399 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
     /* [<][>][^][v][top][bottom][index][help] */
 400 {
 401         WERROR err;
 402         struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
 403         char *valname;
 404         struct registry_value *val;
 405         DATA_BLOB value_blob;
 406         
 407         if ( !key )
 408                 return WERR_BADFID;
 409 
 410         if ( !r->in.name )
 411                 return WERR_INVALID_PARAM;
 412 
 413         DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
 414                  key->key->name));
 415 
 416         err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
 417         if (!W_ERROR_IS_OK(err)) {
 418                 return err;
 419         }
 420 
 421         err = registry_push_value(p->mem_ctx, val, &value_blob);
 422         if (!W_ERROR_IS_OK(err)) {
 423                 return err;
 424         }
 425 
 426         if (r->out.name != NULL) {
 427                 r->out.name->name = valname;
 428         }
 429 
 430         if (r->out.type != NULL) {
 431                 *r->out.type = val->type;
 432         }
 433 
 434         if (r->out.value != NULL) {
 435                 if ((r->out.size == NULL) || (r->out.length == NULL)) {
 436                         return WERR_INVALID_PARAM;
 437                 }
 438 
 439                 if (value_blob.length > *r->out.size) {
 440                         return WERR_MORE_DATA;
 441                 }
 442 
 443                 memcpy( r->out.value, value_blob.data, value_blob.length );
 444         }
 445 
 446         if (r->out.length != NULL) {
 447                 *r->out.length = value_blob.length;
 448         }
 449         if (r->out.size != NULL) {
 450                 *r->out.size = value_blob.length;
 451         }
 452 
 453         return WERR_OK;
 454 }
 455 
 456 /*******************************************************************
 457  reg_shutdwon
 458  ********************************************************************/
 459 
 460 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
     /* [<][>][^][v][top][bottom][index][help] */
 461 {
 462         struct winreg_InitiateSystemShutdownEx s;
 463 
 464         s.in.hostname = r->in.hostname;
 465         s.in.message = r->in.message;
 466         s.in.timeout = r->in.timeout;
 467         s.in.force_apps = r->in.force_apps;
 468         s.in.do_reboot = r->in.do_reboot;
 469         s.in.reason = 0;
 470 
 471         /* thunk down to _winreg_InitiateSystemShutdownEx() 
 472            (just returns a status) */
 473         
 474         return _winreg_InitiateSystemShutdownEx( p, &s );
 475 }
 476 
 477 /*******************************************************************
 478  reg_shutdown_ex
 479  ********************************************************************/
 480 
 481 #define SHUTDOWN_R_STRING "-r"
 482 #define SHUTDOWN_F_STRING "-f"
 483 
 484 
 485 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
     /* [<][>][^][v][top][bottom][index][help] */
 486 {
 487         char *shutdown_script = NULL;
 488         char *msg = NULL;
 489         char *chkmsg = NULL;
 490         fstring str_timeout;
 491         fstring str_reason;
 492         fstring do_reboot;
 493         fstring f;
 494         int ret;
 495         bool can_shutdown;
 496 
 497         shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
 498         if (!shutdown_script) {
 499                 return WERR_NOMEM;
 500         }
 501         if (!*shutdown_script) {
 502                 return WERR_ACCESS_DENIED;
 503         }
 504 
 505         /* pull the message string and perform necessary sanity checks on it */
 506 
 507         if ( r->in.message && r->in.message->string ) {
 508                 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
 509                         return WERR_NOMEM;
 510                 }
 511                 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
 512                 if (!chkmsg) {
 513                         return WERR_NOMEM;
 514                 }
 515                 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
 516         }
 517 
 518         fstr_sprintf(str_timeout, "%d", r->in.timeout);
 519         fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
 520         fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
 521         fstr_sprintf(str_reason, "%d", r->in.reason );
 522 
 523         shutdown_script = talloc_all_string_sub(p->mem_ctx,
 524                                 shutdown_script, "%z", chkmsg ? chkmsg : "");
 525         if (!shutdown_script) {
 526                 return WERR_NOMEM;
 527         }
 528         shutdown_script = talloc_all_string_sub(p->mem_ctx,
 529                                         shutdown_script, "%t", str_timeout);
 530         if (!shutdown_script) {
 531                 return WERR_NOMEM;
 532         }
 533         shutdown_script = talloc_all_string_sub(p->mem_ctx,
 534                                                 shutdown_script, "%r", do_reboot);
 535         if (!shutdown_script) {
 536                 return WERR_NOMEM;
 537         }
 538         shutdown_script = talloc_all_string_sub(p->mem_ctx,
 539                                                 shutdown_script, "%f", f);
 540         if (!shutdown_script) {
 541                 return WERR_NOMEM;
 542         }
 543         shutdown_script = talloc_all_string_sub(p->mem_ctx,
 544                                         shutdown_script, "%x", str_reason);
 545         if (!shutdown_script) {
 546                 return WERR_NOMEM;
 547         }
 548 
 549         can_shutdown = user_has_privileges( p->server_info->ptok,
 550                                             &se_remote_shutdown );
 551 
 552         /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
 553            Take the error return from the script and provide it as the Windows return code. */
 554 
 555         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
 556 
 557         if ( can_shutdown )
 558                 become_root();
 559 
 560         ret = smbrun( shutdown_script, NULL );
 561 
 562         if ( can_shutdown )
 563                 unbecome_root();
 564 
 565         /********** END SeRemoteShutdownPrivilege BLOCK **********/
 566 
 567         DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
 568                 shutdown_script, ret));
 569 
 570         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 571 }
 572 
 573 /*******************************************************************
 574  reg_abort_shutdwon
 575  ********************************************************************/
 576 
 577 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
     /* [<][>][^][v][top][bottom][index][help] */
 578 {
 579         const char *abort_shutdown_script;
 580         int ret;
 581         bool can_shutdown;
 582 
 583         abort_shutdown_script = lp_abort_shutdown_script();
 584 
 585         if (!*abort_shutdown_script)
 586                 return WERR_ACCESS_DENIED;
 587 
 588         can_shutdown = user_has_privileges( p->server_info->ptok,
 589                                             &se_remote_shutdown );
 590 
 591         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
 592 
 593         if ( can_shutdown )
 594                 become_root();
 595 
 596         ret = smbrun( abort_shutdown_script, NULL );
 597 
 598         if ( can_shutdown )
 599                 unbecome_root();
 600 
 601         /********** END SeRemoteShutdownPrivilege BLOCK **********/
 602 
 603         DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
 604                 abort_shutdown_script, ret));
 605 
 606         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 607 }
 608 
 609 /*******************************************************************
 610  ********************************************************************/
 611 
 612 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
     /* [<][>][^][v][top][bottom][index][help] */
 613 {
 614         char *p = NULL;
 615         int num_services = lp_numservices();
 616         int snum = -1;
 617         const char *share_path;
 618         char *fname = *pp_fname;
 619 
 620         /* convert to a unix path, stripping the C:\ along the way */
 621 
 622         if (!(p = valid_share_pathname(ctx, fname))) {
 623                 return -1;
 624         }
 625 
 626         /* has to exist within a valid file share */
 627 
 628         for (snum=0; snum<num_services; snum++) {
 629                 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
 630                         continue;
 631                 }
 632 
 633                 share_path = lp_pathname(snum);
 634 
 635                 /* make sure we have a path (e.g. [homes] ) */
 636                 if (strlen(share_path) == 0) {
 637                         continue;
 638                 }
 639 
 640                 if (strncmp(share_path, p, strlen(share_path)) == 0) {
 641                         break;
 642                 }
 643         }
 644 
 645         *pp_fname = p;
 646         return (snum < num_services) ? snum : -1;
 647 }
 648 
 649 /*******************************************************************
 650  ********************************************************************/
 651 
 652 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 653 {
 654         struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 655         char *fname = NULL;
 656         int             snum;
 657 
 658         if ( !regkey )
 659                 return WERR_BADFID;
 660 
 661         if ( !r->in.filename || !r->in.filename->name )
 662                 return WERR_INVALID_PARAM;
 663 
 664         fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
 665         if (!fname) {
 666                 return WERR_NOMEM;
 667         }
 668 
 669         DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
 670                  "\"%s\"\n", regkey->key->name, fname));
 671 
 672         if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
 673                 return WERR_OBJECT_PATH_INVALID;
 674 
 675         /* user must posses SeRestorePrivilege for this this proceed */
 676 
 677         if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
 678                 return WERR_ACCESS_DENIED;
 679 
 680         DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
 681                  regkey->key->name, fname, lp_servicename(snum) ));
 682 
 683         return reg_restorekey(regkey, fname);
 684 }
 685 
 686 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 687 {
 688         struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 689         char *fname = NULL;
 690         int snum = -1;
 691 
 692         if ( !regkey )
 693                 return WERR_BADFID;
 694 
 695         if ( !r->in.filename || !r->in.filename->name )
 696                 return WERR_INVALID_PARAM;
 697 
 698         fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
 699         if (!fname) {
 700                 return WERR_NOMEM;
 701         }
 702 
 703         DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
 704                  regkey->key->name, fname));
 705 
 706         if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
 707                 return WERR_OBJECT_PATH_INVALID;
 708 
 709         DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
 710                  regkey->key->name, fname, lp_servicename(snum) ));
 711 
 712         return reg_savekey(regkey, fname);
 713 }
 714 
 715 /*******************************************************************
 716  ********************************************************************/
 717 
 718 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
     /* [<][>][^][v][top][bottom][index][help] */
 719 {
 720         /* fill in your code here if you think this call should
 721            do anything */
 722 
 723         p->rng_fault_state = True;
 724         return WERR_NOT_SUPPORTED;
 725 }
 726 
 727 /*******************************************************************
 728  ********************************************************************/
 729 
 730 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 731 {
 732         struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
 733         struct registry_key *new_key;
 734         WERROR result;
 735 
 736         if ( !parent )
 737                 return WERR_BADFID;
 738 
 739         DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
 740                    "subkey name '%s'\n", parent->key->name, r->in.name.name));
 741 
 742         result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
 743                                &new_key, r->out.action_taken);
 744         if (!W_ERROR_IS_OK(result)) {
 745                 return result;
 746         }
 747 
 748         if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
 749                 TALLOC_FREE(new_key);
 750                 return WERR_BADFILE;
 751         }
 752 
 753         return WERR_OK;
 754 }
 755 
 756 /*******************************************************************
 757  ********************************************************************/
 758 
 759 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
     /* [<][>][^][v][top][bottom][index][help] */
 760 {
 761         struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 762         struct registry_value *val;
 763         WERROR status;
 764 
 765         if ( !key )
 766                 return WERR_BADFID;
 767 
 768         DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", 
 769                          key->key->name, r->in.name.name));
 770 
 771         status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data, 
 772                                                                  r->in.size, r->in.size);
 773         if (!W_ERROR_IS_OK(status)) {
 774                 return status;
 775         }
 776 
 777         return reg_setvalue(key, r->in.name.name, val);
 778 }
 779 
 780 /*******************************************************************
 781  ********************************************************************/
 782 
 783 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 784 {
 785         struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
 786 
 787         if ( !parent )
 788                 return WERR_BADFID;
 789 
 790         return reg_deletekey(parent, r->in.key.name);
 791 }
 792 
 793 
 794 /*******************************************************************
 795  ********************************************************************/
 796 
 797 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
     /* [<][>][^][v][top][bottom][index][help] */
 798 {
 799         struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 800         
 801         if ( !key )
 802                 return WERR_BADFID;
 803 
 804         return reg_deletevalue(key, r->in.value.name);
 805 }
 806 
 807 /*******************************************************************
 808  ********************************************************************/
 809 
 810 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
     /* [<][>][^][v][top][bottom][index][help] */
 811 {
 812         struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 813         WERROR err;
 814         struct security_descriptor *secdesc;
 815         uint8 *data;
 816         size_t len;
 817 
 818         if ( !key )
 819                 return WERR_BADFID;
 820                 
 821         /* access checks first */
 822         
 823         if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
 824                 return WERR_ACCESS_DENIED;
 825 
 826         err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
 827         if (!W_ERROR_IS_OK(err)) {
 828                 return err;
 829         }
 830 
 831         err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
 832                                                    &data, &len));
 833         if (!W_ERROR_IS_OK(err)) {
 834                 return err;
 835         }
 836 
 837         if (len > r->out.sd->size) {
 838                 r->out.sd->size = len;
 839                 return WERR_INSUFFICIENT_BUFFER;
 840         }
 841 
 842         r->out.sd->size = len;
 843         r->out.sd->len = len;
 844         r->out.sd->data = data;
 845                 
 846         return WERR_OK;
 847 }
 848 
 849 /*******************************************************************
 850  ********************************************************************/
 851 
 852 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
     /* [<][>][^][v][top][bottom][index][help] */
 853 {
 854         struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 855         struct security_descriptor *secdesc;
 856         WERROR err;
 857 
 858         if ( !key )
 859                 return WERR_BADFID;
 860                 
 861         /* access checks first */
 862         
 863         if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
 864                 return WERR_ACCESS_DENIED;
 865 
 866         err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
 867                                                      r->in.sd->len, &secdesc));
 868         if (!W_ERROR_IS_OK(err)) {
 869                 return err;
 870         }
 871 
 872         return reg_setkeysecurity(key, secdesc);
 873 }
 874 
 875 /*******************************************************************
 876  ********************************************************************/
 877 
 878 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 879 {
 880         /* I'm just replying OK because there's not a lot 
 881            here I see to do i  --jerry */
 882         
 883         return WERR_OK;
 884 }
 885 
 886 /*******************************************************************
 887  ********************************************************************/
 888 
 889 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 890 {
 891         /* fill in your code here if you think this call should
 892            do anything */
 893 
 894         p->rng_fault_state = True;
 895         return WERR_NOT_SUPPORTED;
 896 }
 897 
 898 /*******************************************************************
 899  ********************************************************************/
 900 
 901 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 902 {
 903         /* fill in your code here if you think this call should
 904            do anything */
 905 
 906         p->rng_fault_state = True;
 907         return WERR_NOT_SUPPORTED;
 908 }
 909 
 910 /*******************************************************************
 911  ********************************************************************/
 912 
 913 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
     /* [<][>][^][v][top][bottom][index][help] */
 914 {
 915         /* fill in your code here if you think this call should
 916            do anything */
 917 
 918         p->rng_fault_state = True;
 919         return WERR_NOT_SUPPORTED;
 920 }
 921 
 922 /*******************************************************************
 923  ********************************************************************/
 924 
 925 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
     /* [<][>][^][v][top][bottom][index][help] */
 926 {
 927         /* fill in your code here if you think this call should
 928            do anything */
 929 
 930         p->rng_fault_state = True;
 931         return WERR_NOT_SUPPORTED;
 932 }
 933 
 934 /*******************************************************************
 935  ********************************************************************/
 936 
 937 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
     /* [<][>][^][v][top][bottom][index][help] */
 938 {
 939         /* fill in your code here if you think this call should
 940            do anything */
 941 
 942         p->rng_fault_state = True;
 943         return WERR_NOT_SUPPORTED;
 944 }
 945 
 946 /*******************************************************************
 947  ********************************************************************/
 948 
 949 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
     /* [<][>][^][v][top][bottom][index][help] */
 950 {
 951         /* fill in your code here if you think this call should
 952            do anything */
 953 
 954         p->rng_fault_state = True;
 955         return WERR_NOT_SUPPORTED;
 956 }
 957 

/* [<][>][^][v][top][bottom][index][help] */