rpc_server/srv_reg_nt.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  RPC Pipe client / server routines
00004  *  Copyright (C) Andrew Tridgell               1992-1997.
00005  *  Copyright (C) Luke Kenneth Casson Leighton  1996-1997.
00006  *  Copyright (C) Paul Ashton                        1997.
00007  *  Copyright (C) Jeremy Allison                     2001.
00008  *  Copyright (C) Gerald Carter                      2002-2005.
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *  
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *  
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023  */
00024 
00025 /* Implementation of registry functions. */
00026 
00027 #include "includes.h"
00028 #include "regfio.h"
00029 
00030 #undef DBGC_CLASS
00031 #define DBGC_CLASS DBGC_RPC_SRV
00032 
00033 static struct generic_mapping reg_generic_map = 
00034         { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
00035 
00036 
00037 /******************************************************************
00038  free() function for REGISTRY_KEY
00039  *****************************************************************/
00040  
00041 static void free_regkey_info(void *ptr)
00042 {
00043         regkey_close_internal( (REGISTRY_KEY*)ptr );
00044 }
00045 
00046 /******************************************************************
00047  Find a registry key handle and return a REGISTRY_KEY
00048  *****************************************************************/
00049 
00050 static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
00051 {
00052         REGISTRY_KEY *regkey = NULL;
00053 
00054         if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
00055                 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
00056                 return NULL;
00057         }
00058 
00059         return regkey;
00060 }
00061 
00062 
00063 /*******************************************************************
00064  Function for open a new registry handle and creating a handle 
00065  Note that P should be valid & hnd should already have space
00066  
00067  When we open a key, we store the full path to the key as 
00068  HK[LM|U]<key><key>\...
00069  *******************************************************************/
00070  
00071 static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, 
00072                                  REGISTRY_KEY **keyinfo, REGISTRY_KEY *parent,
00073                                  const char *subkeyname, uint32 access_desired  )
00074 {
00075         pstring         keypath;
00076         int             path_len;
00077         WERROR          result = WERR_OK;
00078 
00079         /* create a full registry path and strip any trailing '\' 
00080            characters */
00081            
00082         pstr_sprintf( keypath, "%s%s%s", 
00083                 parent ? parent->name : "",
00084                 parent ? "\\" : "", 
00085                 subkeyname );
00086         
00087         path_len = strlen( keypath );
00088         if ( path_len && keypath[path_len-1] == '\\' )
00089                 keypath[path_len-1] = '\0';
00090         
00091         /* now do the internal open */
00092                 
00093         result = regkey_open_internal( keyinfo, keypath, p->pipe_user.nt_user_token, access_desired );
00094         if ( !W_ERROR_IS_OK(result) )
00095                 return result;
00096         
00097         if ( !create_policy_hnd( p, hnd, free_regkey_info, *keyinfo ) ) {
00098                 result = WERR_BADFILE; 
00099                 regkey_close_internal( *keyinfo );
00100         }
00101         
00102         return result;
00103 }
00104 
00105 /*******************************************************************
00106  Function for open a new registry handle and creating a handle 
00107  Note that P should be valid & hnd should already have space
00108  *******************************************************************/
00109 
00110 static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
00111 {
00112         REGISTRY_KEY *regkey = find_regkey_index_by_hnd(p, hnd);
00113         
00114         if ( !regkey ) {
00115                 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
00116                 return False;
00117         }
00118         
00119         close_policy_hnd(p, hnd);
00120         
00121         return True;
00122 }
00123 
00124 /********************************************************************
00125  retrieve information about the subkeys
00126  *******************************************************************/
00127  
00128 static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen )
00129 {
00130         int             num_subkeys, i;
00131         uint32          max_len;
00132         REGSUBKEY_CTR   *subkeys;
00133         uint32          len;
00134         
00135         if ( !key )
00136                 return False;
00137 
00138         if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) )
00139                 return False;
00140 
00141         if ( fetch_reg_keys( key, subkeys ) == -1 )
00142                 return False;
00143 
00144         /* find the longest string */
00145         
00146         max_len = 0;
00147         num_subkeys = regsubkey_ctr_numkeys( subkeys );
00148         
00149         for ( i=0; i<num_subkeys; i++ ) {
00150                 len = strlen( regsubkey_ctr_specific_key(subkeys, i) );
00151                 max_len = MAX(max_len, len);
00152         }
00153 
00154         *maxnum = num_subkeys;
00155         *maxlen = max_len*2;
00156         
00157         TALLOC_FREE( subkeys );
00158         
00159         return True;
00160 }
00161 
00162 /********************************************************************
00163  retrieve information about the values.  
00164  *******************************************************************/
00165  
00166 static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum, 
00167                                     uint32 *maxlen, uint32 *maxsize )
00168 {
00169         REGVAL_CTR      *values;
00170         REGISTRY_VALUE  *val;
00171         uint32          sizemax, lenmax;
00172         int             i, num_values;
00173         
00174         if ( !key )
00175                 return False;
00176 
00177         if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) )
00178                 return False;
00179         
00180         if ( fetch_reg_values( key, values ) == -1 )
00181                 return False;
00182         
00183         lenmax = sizemax = 0;
00184         num_values = regval_ctr_numvals( values );
00185         
00186         val = regval_ctr_specific_value( values, 0 );
00187         
00188         for ( i=0; i<num_values && val; i++ ) 
00189         {
00190                 lenmax  = MAX(lenmax,  val->valuename ? strlen(val->valuename)+1 : 0 );
00191                 sizemax = MAX(sizemax, val->size );
00192                 
00193                 val = regval_ctr_specific_value( values, i );
00194         }
00195 
00196         *maxnum   = num_values;
00197         *maxlen   = lenmax;
00198         *maxsize  = sizemax;
00199         
00200         TALLOC_FREE( values );
00201         
00202         return True;
00203 }
00204 
00205 
00206 /********************************************************************
00207  reg_close
00208  ********************************************************************/
00209 
00210 WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
00211 {
00212         /* close the policy handle */
00213 
00214         if (!close_registry_key(p, &q_u->pol))
00215                 return WERR_BADFID; 
00216 
00217         return WERR_OK;
00218 }
00219 
00220 /*******************************************************************
00221  ********************************************************************/
00222 
00223 WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
00224 {
00225         REGISTRY_KEY *keyinfo;
00226         
00227         return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKLM, q_u->access );
00228 }
00229 
00230 /*******************************************************************
00231  ********************************************************************/
00232 
00233 WERROR _reg_open_hkpd(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
00234 {
00235         REGISTRY_KEY *keyinfo;
00236         
00237         return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPD, q_u->access );
00238 }
00239 
00240 /*******************************************************************
00241  ********************************************************************/
00242 
00243 WERROR _reg_open_hkpt(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
00244 {
00245         REGISTRY_KEY *keyinfo;
00246         
00247         return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPT, q_u->access );
00248 }
00249 
00250 /*******************************************************************
00251  ********************************************************************/
00252 
00253 WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
00254 {
00255         REGISTRY_KEY *keyinfo;
00256         
00257         return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKCR, q_u->access );
00258 }
00259 
00260 /*******************************************************************
00261  ********************************************************************/
00262 
00263 WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
00264 {
00265         REGISTRY_KEY *keyinfo;
00266         
00267         return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKU, q_u->access );
00268 }
00269 
00270 /*******************************************************************
00271  reg_reply_open_entry
00272  ********************************************************************/
00273 
00274 WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
00275 {
00276         fstring name;
00277         REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->pol);
00278         REGISTRY_KEY *newkey = NULL;
00279         uint32 check_rights;
00280 
00281         if ( !parent )
00282                 return WERR_BADFID;
00283 
00284         rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
00285         
00286         /* check granted access first; what is the correct mask here? */
00287 
00288         check_rights = ( SEC_RIGHTS_ENUM_SUBKEYS|
00289                          SEC_RIGHTS_CREATE_SUBKEY|
00290                          SEC_RIGHTS_QUERY_VALUE|
00291                          SEC_RIGHTS_SET_VALUE);
00292 
00293         if ( !(parent->access_granted & check_rights) ) {
00294                 DEBUG(8,("Rights check failed, parent had %04x, check_rights %04x\n",parent->access_granted, check_rights));
00295                 return WERR_ACCESS_DENIED;
00296         }
00297         
00298         /* 
00299          * very crazy, but regedit.exe on Win2k will attempt to call 
00300          * REG_OPEN_ENTRY with a keyname of "".  We should return a new 
00301          * (second) handle here on the key->name.  regedt32.exe does 
00302          * not do this stupidity.   --jerry
00303          */
00304          
00305         return open_registry_key( p, &r_u->handle, &newkey, parent, name, q_u->access );
00306 }
00307 
00308 /*******************************************************************
00309  reg_reply_info
00310  ********************************************************************/
00311 
00312 WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VALUE *r_u)
00313 {
00314         WERROR                  status = WERR_BADFILE;
00315         fstring                 name;
00316         REGISTRY_KEY            *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00317         REGISTRY_VALUE          *val = NULL;
00318         REGVAL_CTR              *regvals;
00319         int                     i;
00320 
00321         if ( !regkey )
00322                 return WERR_BADFID;
00323                 
00324         DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
00325         DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->type));
00326         
00327         rpcstr_pull(name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0);
00328 
00329         DEBUG(5,("_reg_info: looking up value: [%s]\n", name));
00330 
00331         if ( !(regvals = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) 
00332                 return WERR_NOMEM;
00333         
00334         /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
00335         if(regkey->type == REG_KEY_HKPD) 
00336         {
00337                 if(strequal(name, "Global"))
00338                 {
00339                         uint32 outbuf_len;
00340                         prs_struct prs_hkpd;
00341                         prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL);
00342                         status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, NULL);
00343                         regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
00344                                             prs_hkpd.data_p, outbuf_len);
00345                         val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
00346                         prs_mem_free(&prs_hkpd);
00347                 }
00348                 else if(strequal(name, "Counter 009"))
00349                 {
00350                         uint32 base_index;
00351                         uint32 buffer_size;
00352                         char *buffer;
00353                         
00354                         buffer = NULL;
00355                         base_index = reg_perfcount_get_base_index();
00356                         buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
00357                         regval_ctr_addvalue(regvals, "Counter 009", 
00358                                             REG_MULTI_SZ, buffer, buffer_size);
00359                         
00360                         val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
00361                         
00362                         if(buffer_size > 0)
00363                         {
00364                                 SAFE_FREE(buffer);
00365                                 status = WERR_OK;
00366                         }
00367                 }
00368                 else if(strequal(name, "Explain 009"))
00369                 {               
00370                         uint32 base_index;
00371                         uint32 buffer_size;
00372                         char *buffer;
00373                         
00374                         buffer = NULL;
00375                         base_index = reg_perfcount_get_base_index();
00376                         buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
00377                         regval_ctr_addvalue(regvals, "Explain 009", 
00378                                             REG_MULTI_SZ, buffer, buffer_size);
00379                         
00380                         val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
00381                         
00382                         if(buffer_size > 0)
00383                         {
00384                                 SAFE_FREE(buffer);
00385                                 status = WERR_OK;
00386                         }
00387                 }
00388                 else if(isdigit(name[0]))
00389                 {
00390                         /* we probably have a request for a specific object here */
00391                         uint32 outbuf_len;
00392                         prs_struct prs_hkpd;
00393                         prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL);
00394                         status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, name);
00395                         regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
00396                                             prs_hkpd.data_p, outbuf_len);
00397                         
00398                         val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
00399                         prs_mem_free(&prs_hkpd);
00400                 }
00401                 else
00402                 {
00403                         DEBUG(3,("Unsupported key name [%s] for HKPD.\n", name));
00404                         return WERR_BADFILE;
00405                 }
00406         }
00407         /* HKPT calls can be handled out of reg_dynamic.c with the hkpt_params handler */
00408         else
00409         {
00410             for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ ) 
00411             {
00412                 DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
00413                 if ( strequal( val->valuename, name ) ) {
00414                         DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
00415                         status = WERR_OK;
00416                         break;
00417                 }
00418                 
00419                 free_registry_value( val );
00420             }
00421         }
00422 
00423         init_reg_r_query_value(q_u->ptr_buf, r_u, val, status);
00424         
00425         TALLOC_FREE( regvals );
00426         free_registry_value( val );
00427 
00428         return status;
00429 }
00430 
00431 /*****************************************************************************
00432  Implementation of REG_QUERY_KEY
00433  ****************************************************************************/
00434  
00435 WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u)
00436 {
00437         WERROR  status = WERR_OK;
00438         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00439         
00440         if ( !regkey )
00441                 return WERR_BADFID; 
00442         
00443         if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) ) {
00444                 DEBUG(0,("_reg_query_key: get_subkey_information() failed!\n"));
00445                 return WERR_ACCESS_DENIED;
00446         }
00447                 
00448         if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) ) {
00449                 DEBUG(0,("_reg_query_key: get_value_information() failed!\n"));
00450                 return WERR_ACCESS_DENIED;      
00451         }
00452 
00453                 
00454         r_u->sec_desc = 0x00000078;     /* size for key's sec_desc */
00455         
00456         /* Win9x set this to 0x0 since it does not keep timestamps.
00457            Doing the same here for simplicity   --jerry */
00458            
00459         ZERO_STRUCT(r_u->mod_time);     
00460 
00461         return status;
00462 }
00463 
00464 
00465 /*****************************************************************************
00466  Implementation of REG_GETVERSION
00467  ****************************************************************************/
00468  
00469 WERROR _reg_getversion(pipes_struct *p, REG_Q_GETVERSION *q_u, REG_R_GETVERSION *r_u)
00470 {
00471         WERROR  status = WERR_OK;
00472         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00473         
00474         if ( !regkey )
00475                 return WERR_BADFID;
00476         
00477         r_u->win_version = 0x00000005;  /* Windows 2000 registry API version */
00478         
00479         return status;
00480 }
00481 
00482 
00483 /*****************************************************************************
00484  Implementation of REG_ENUM_KEY
00485  ****************************************************************************/
00486  
00487 WERROR _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u)
00488 {
00489         WERROR  status = WERR_OK;
00490         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00491         char            *subkey = NULL;
00492         
00493         
00494         if ( !regkey )
00495                 return WERR_BADFID; 
00496 
00497         DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name));
00498         
00499         if ( !fetch_reg_keys_specific( regkey, &subkey, q_u->key_index ) )
00500         {
00501                 status = WERR_NO_MORE_ITEMS;
00502                 goto done;
00503         }
00504         
00505         DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n", subkey));
00506         
00507         /* subkey has the string name now */
00508         
00509         init_reg_r_enum_key( r_u, subkey );
00510         
00511 done:   
00512         SAFE_FREE( subkey );
00513         return status;
00514 }
00515 
00516 /*****************************************************************************
00517  Implementation of REG_ENUM_VALUE
00518  ****************************************************************************/
00519  
00520 WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
00521 {
00522         WERROR  status = WERR_OK;
00523         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00524         REGISTRY_VALUE  *val;
00525         
00526         
00527         if ( !regkey )
00528                 return WERR_BADFID; 
00529 
00530         DEBUG(8,("_reg_enum_value: enumerating values for key [%s]\n", regkey->name));
00531 
00532         if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) ) {
00533                 status = WERR_NO_MORE_ITEMS;
00534                 goto done;
00535         }
00536 
00537 #if 0   /* JERRY TEST CODE */
00538         if ( val->type == REG_MULTI_SZ ) {
00539                 char **str;
00540                 int num_strings = regval_convert_multi_sz( (uint16*)regval_data_p(val), regval_size(val), &str );
00541                 uint16 *buffer;
00542                 size_t buf_size;
00543                 
00544                 
00545                 if ( num_strings )
00546                         buf_size = regval_build_multi_sz( str, &buffer );
00547                 
00548                 TALLOC_FREE( str );
00549                 TALLOC_FREE( buffer );
00550         }
00551 #endif
00552         
00553         DEBUG(10,("_reg_enum_value: retrieved value named  [%s]\n", val->valuename));
00554         
00555         /* subkey has the string name now */
00556         
00557         init_reg_r_enum_val( r_u, val );
00558 
00559 done:   
00560         free_registry_value( val );
00561         
00562         return status;
00563 }
00564 
00565 
00566 /*******************************************************************
00567  reg_shutdwon
00568  ********************************************************************/
00569 
00570 WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
00571 {
00572         REG_Q_SHUTDOWN_EX q_u_ex;
00573         REG_R_SHUTDOWN_EX r_u_ex;
00574         
00575         /* copy fields (including stealing memory) */
00576         
00577         q_u_ex.server  = q_u->server;
00578         q_u_ex.message = q_u->message;
00579         q_u_ex.timeout = q_u->timeout;
00580         q_u_ex.force   = q_u->force;
00581         q_u_ex.reboot  = q_u->reboot;
00582         q_u_ex.reason  = 0x0;   /* don't care for now */
00583         
00584         /* thunk down to _reg_shutdown_ex() (just returns a status) */
00585         
00586         return _reg_shutdown_ex( p, &q_u_ex, &r_u_ex );
00587 }
00588 
00589 /*******************************************************************
00590  reg_shutdown_ex
00591  ********************************************************************/
00592 
00593 #define SHUTDOWN_R_STRING "-r"
00594 #define SHUTDOWN_F_STRING "-f"
00595 
00596 
00597 WERROR _reg_shutdown_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_EX *r_u)
00598 {
00599         pstring shutdown_script;
00600         pstring message;
00601         pstring chkmsg;
00602         fstring timeout;
00603         fstring reason;
00604         fstring r;
00605         fstring f;
00606         int ret;
00607         BOOL can_shutdown;
00608         
00609 
00610         pstrcpy(shutdown_script, lp_shutdown_script());
00611         
00612         if ( !*shutdown_script )
00613                 return WERR_ACCESS_DENIED;
00614 
00615         /* pull the message string and perform necessary sanity checks on it */
00616 
00617         pstrcpy( message, "" );
00618         if ( q_u->message ) {
00619                 UNISTR2 *msg_string = q_u->message->string;
00620                 
00621                 rpcstr_pull( message, msg_string->buffer, sizeof(message), msg_string->uni_str_len*2, 0 );
00622         }
00623         alpha_strcpy (chkmsg, message, NULL, sizeof(message));
00624                 
00625         fstr_sprintf(timeout, "%d", q_u->timeout);
00626         fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
00627         fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
00628         fstr_sprintf( reason, "%d", q_u->reason );
00629 
00630         all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
00631         all_string_sub( shutdown_script, "%t", timeout, sizeof(shutdown_script) );
00632         all_string_sub( shutdown_script, "%r", r, sizeof(shutdown_script) );
00633         all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
00634         all_string_sub( shutdown_script, "%x", reason, sizeof(shutdown_script) );
00635 
00636         can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
00637                 
00638         /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
00639            Take the error return from the script and provide it as the Windows return code. */
00640            
00641         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
00642         
00643         if ( can_shutdown ) 
00644                 become_root();
00645 
00646         ret = smbrun( shutdown_script, NULL );
00647                 
00648         if ( can_shutdown )
00649                 unbecome_root();
00650 
00651         /********** END SeRemoteShutdownPrivilege BLOCK **********/
00652         
00653         DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
00654                 shutdown_script, ret));
00655                 
00656 
00657         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
00658 }
00659 
00660 
00661 
00662 
00663 /*******************************************************************
00664  reg_abort_shutdwon
00665  ********************************************************************/
00666 
00667 WERROR _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
00668 {
00669         pstring abort_shutdown_script;
00670         int ret;
00671         BOOL can_shutdown;
00672 
00673         pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
00674 
00675         if ( !*abort_shutdown_script )
00676                 return WERR_ACCESS_DENIED;
00677                 
00678         can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
00679                 
00680         /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
00681         
00682         if ( can_shutdown )
00683                 become_root();
00684                 
00685         ret = smbrun( abort_shutdown_script, NULL );
00686         
00687         if ( can_shutdown )
00688                 unbecome_root();
00689                 
00690         /********** END SeRemoteShutdownPrivilege BLOCK **********/
00691 
00692         DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
00693                 abort_shutdown_script, ret));
00694                 
00695 
00696         return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
00697 }
00698 
00699 /*******************************************************************
00700  ********************************************************************/
00701 
00702 static int validate_reg_filename( pstring fname )
00703 {
00704         char *p;
00705         int num_services = lp_numservices();
00706         int snum;
00707         pstring share_path;
00708         pstring unix_fname;
00709         
00710         /* convert to a unix path, stripping the C:\ along the way */
00711         
00712         if ( !(p = valid_share_pathname( fname ) ))
00713                 return -1;
00714 
00715         /* has to exist within a valid file share */
00716                         
00717         for ( snum=0; snum<num_services; snum++ ) {
00718         
00719                 if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
00720                         continue;
00721                 
00722                 pstrcpy( share_path, lp_pathname(snum) );
00723 
00724                 /* make sure we have a path (e.g. [homes] ) */
00725 
00726                 if ( strlen( share_path ) == 0 )
00727                         continue;
00728 
00729                 if ( strncmp( share_path, p, strlen( share_path )) == 0 )
00730                         break;
00731         }
00732         
00733         /* p and fname are overlapping memory so copy out and back in again */
00734         
00735         pstrcpy( unix_fname, p );
00736         pstrcpy( fname, unix_fname );
00737         
00738         return (snum < num_services) ? snum : -1;
00739 }
00740 
00741 /*******************************************************************
00742  Note: topkeypat is the *full* path that this *key will be 
00743  loaded into (including the name of the key)
00744  ********************************************************************/
00745 
00746 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
00747                              REGF_NK_REC *key )
00748 {
00749         REGF_NK_REC *subkey;
00750         REGISTRY_KEY registry_key;
00751         REGVAL_CTR *values;
00752         REGSUBKEY_CTR *subkeys;
00753         int i;
00754         pstring path;
00755         WERROR result = WERR_OK;
00756         
00757         /* initialize the REGISTRY_KEY structure */
00758         
00759         if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
00760                 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
00761                         topkeypath ));
00762                 return WERR_BADFILE;
00763         }
00764         pstrcpy( registry_key.name, topkeypath );
00765         
00766         /* now start parsing the values and subkeys */
00767 
00768         if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
00769                 return WERR_NOMEM;
00770         
00771         if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
00772                 return WERR_NOMEM;
00773 
00774         /* copy values into the REGVAL_CTR */
00775         
00776         for ( i=0; i<key->num_values; i++ ) {
00777                 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
00778                         (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
00779         }
00780 
00781         /* copy subkeys into the REGSUBKEY_CTR */
00782         
00783         key->subkey_index = 0;
00784         while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
00785                 regsubkey_ctr_addkey( subkeys, subkey->keyname );
00786         }
00787         
00788         /* write this key and values out */
00789         
00790         if ( !store_reg_values( &registry_key, values ) 
00791                 || !store_reg_keys( &registry_key, subkeys ) )
00792         {
00793                 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
00794                 result = WERR_REG_IO_FAILURE;
00795         }
00796         
00797         TALLOC_FREE( subkeys );
00798         
00799         if ( !W_ERROR_IS_OK(result) )
00800                 return result;
00801         
00802         /* now continue to load each subkey registry tree */
00803 
00804         key->subkey_index = 0;
00805         while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
00806                 pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname );
00807                 result = reg_load_tree( regfile, path, subkey );
00808                 if ( !W_ERROR_IS_OK(result) )
00809                         break;
00810         }
00811 
00812         return result;
00813 }
00814 
00815 /*******************************************************************
00816  ********************************************************************/
00817 
00818 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
00819 {
00820         REGF_FILE *regfile;
00821         REGF_NK_REC *rootkey;
00822         WERROR result;
00823                 
00824         /* open the registry file....fail if the file already exists */
00825         
00826         if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
00827                 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", 
00828                         fname, strerror(errno) ));
00829                 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
00830         }
00831         
00832         /* get the rootkey from the regf file and then load the tree
00833            via recursive calls */
00834            
00835         if ( !(rootkey = regfio_rootkey( regfile )) ) {
00836                 regfio_close( regfile );
00837                 return WERR_REG_FILE_INVALID;
00838         }
00839         
00840         result = reg_load_tree( regfile, krecord->name, rootkey );
00841                 
00842         /* cleanup */
00843         
00844         regfio_close( regfile );
00845         
00846         return result;
00847 }
00848 
00849 /*******************************************************************
00850  ********************************************************************/
00851 
00852 WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY  *q_u, REG_R_RESTORE_KEY *r_u)
00853 {
00854         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
00855         pstring         filename;
00856         int             snum;
00857         
00858         if ( !regkey )
00859                 return WERR_BADFID; 
00860 
00861         rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
00862 
00863         DEBUG(8,("_reg_restore_key: verifying restore of key [%s] from \"%s\"\n", regkey->name, filename));
00864 
00865         if ( (snum = validate_reg_filename( filename )) == -1 )
00866                 return WERR_OBJECT_PATH_INVALID;
00867                 
00868         /* user must posses SeRestorePrivilege for this this proceed */
00869         
00870         if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
00871                 return WERR_ACCESS_DENIED;
00872                 
00873         DEBUG(2,("_reg_restore_key: Restoring [%s] from %s in share %s\n", regkey->name, filename, lp_servicename(snum) ));
00874 
00875         return restore_registry_key( regkey, filename );
00876 }
00877 
00878 /********************************************************************
00879 ********************************************************************/
00880 
00881 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
00882                               REGF_NK_REC *parent, SEC_DESC *sec_desc )
00883 {
00884         REGF_NK_REC *key;
00885         REGVAL_CTR *values;
00886         REGSUBKEY_CTR *subkeys;
00887         int i, num_subkeys;
00888         pstring key_tmp;
00889         char *keyname, *parentpath;
00890         pstring subkeypath;
00891         char *subkeyname;
00892         REGISTRY_KEY registry_key;
00893         WERROR result = WERR_OK;
00894         
00895         if ( !regfile )
00896                 return WERR_GENERAL_FAILURE;
00897                 
00898         if ( !keypath )
00899                 return WERR_OBJECT_PATH_INVALID;
00900                 
00901         /* split up the registry key path */
00902         
00903         pstrcpy( key_tmp, keypath );
00904         if ( !reg_split_key( key_tmp, &parentpath, &keyname ) )
00905                 return WERR_OBJECT_PATH_INVALID;
00906 
00907         if ( !keyname )
00908                 keyname = parentpath;
00909 
00910         /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
00911         
00912         ZERO_STRUCT( registry_key );
00913         pstrcpy( registry_key.name, keypath );
00914         if ( !(registry_key.hook = reghook_cache_find( registry_key.name )) )
00915                 return WERR_BADFILE;
00916 
00917         
00918         /* lookup the values and subkeys */
00919         
00920         if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
00921                 return WERR_NOMEM;
00922 
00923         if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
00924                 return WERR_NOMEM;
00925 
00926         fetch_reg_keys( &registry_key, subkeys );
00927         fetch_reg_values( &registry_key, values );
00928 
00929         /* write out this key */
00930                 
00931         if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
00932                 result = WERR_CAN_NOT_COMPLETE;
00933                 goto done;
00934         }
00935 
00936         /* write each one of the subkeys out */
00937 
00938         num_subkeys = regsubkey_ctr_numkeys( subkeys );
00939         for ( i=0; i<num_subkeys; i++ ) {
00940                 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
00941                 pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
00942                 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
00943                 if ( !W_ERROR_IS_OK(result) )
00944                         goto done;
00945         }
00946 
00947         DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
00948 
00949 done:
00950         TALLOC_FREE( subkeys );
00951 
00952         return result;
00953 }
00954 
00955 /*******************************************************************
00956  ********************************************************************/
00957 
00958 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
00959 {
00960         DOM_SID adm_sid, owner_sid;
00961         SEC_ACE ace[2];         /* at most 2 entries */
00962         SEC_ACCESS mask;
00963         SEC_ACL *psa = NULL;
00964         size_t sd_size;
00965 
00966         /* set the owner to BUILTIN\Administrator */
00967 
00968         sid_copy(&owner_sid, &global_sid_Builtin);
00969         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
00970         
00971 
00972         /* basic access for Everyone */
00973 
00974         init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
00975         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00976 
00977         /* add Full Access 'BUILTIN\Administrators' */
00978 
00979         init_sec_access(&mask, reg_generic_map.generic_all);
00980         sid_copy(&adm_sid, &global_sid_Builtin);
00981         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
00982         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00983 
00984         /* create the security descriptor */
00985 
00986         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
00987                 return WERR_NOMEM;
00988 
00989         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
00990                 return WERR_NOMEM;
00991 
00992         return WERR_OK;
00993 }
00994 
00995 /*******************************************************************
00996  ********************************************************************/
00997 
00998 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
00999 {
01000         REGF_FILE *regfile;
01001         WERROR result;
01002         SEC_DESC *sd = NULL;
01003         
01004         /* open the registry file....fail if the file already exists */
01005         
01006         if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
01007                 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", 
01008                         fname, strerror(errno) ));
01009                 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
01010         }
01011         
01012         if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
01013                 regfio_close( regfile );
01014                 return result;
01015         }
01016                 
01017         /* write the registry tree to the file  */
01018         
01019         result = reg_write_tree( regfile, krecord->name, NULL, sd );
01020                 
01021         /* cleanup */
01022         
01023         regfio_close( regfile );
01024         
01025         return result;
01026 }
01027 
01028 /*******************************************************************
01029  ********************************************************************/
01030 
01031 WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY  *q_u, REG_R_SAVE_KEY *r_u)
01032 {
01033         REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
01034         pstring         filename;
01035         int             snum;
01036         
01037         if ( !regkey )
01038                 return WERR_BADFID; 
01039 
01040         rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
01041 
01042         DEBUG(8,("_reg_save_key: verifying backup of key [%s] to \"%s\"\n", regkey->name, filename));
01043         
01044         if ( (snum = validate_reg_filename( filename )) == -1 )
01045                 return WERR_OBJECT_PATH_INVALID;
01046                 
01047         DEBUG(2,("_reg_save_key: Saving [%s] to %s in share %s\n", regkey->name, filename, lp_servicename(snum) ));
01048                 
01049         return backup_registry_key( regkey, filename );
01050 }
01051 
01052 /*******************************************************************
01053  ********************************************************************/
01054 
01055 WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREATE_KEY_EX *r_u)
01056 {
01057         REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
01058         REGISTRY_KEY *newparentinfo, *keyinfo;
01059         POLICY_HND newparent_handle;
01060         REGSUBKEY_CTR *subkeys;
01061         BOOL write_result;
01062         pstring name;
01063         WERROR result;
01064 
01065         if ( !parent )
01066                 return WERR_BADFID;
01067                 
01068         rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
01069         
01070         /* ok.  Here's what we do.  */
01071 
01072         if ( strrchr( name, '\\' ) ) {
01073                 pstring newkeyname;
01074                 char *ptr;
01075                 
01076                 /* (1) check for enumerate rights on the parent handle.  CLients can try 
01077                        create things like 'SOFTWARE\Samba' on the HKLM handle. 
01078                    (2) open the path to the child parent key if necessary */
01079         
01080                 if ( !(parent->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) )
01081                         return WERR_ACCESS_DENIED;
01082                 
01083                 pstrcpy( newkeyname, name );
01084                 ptr = strrchr( newkeyname, '\\' );
01085                 *ptr = '\0';
01086 
01087                 result = open_registry_key( p, &newparent_handle, &newparentinfo, 
01088                         parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) );
01089                         
01090                 if ( !W_ERROR_IS_OK(result) )
01091                         return result;
01092 
01093                 /* copy the new key name (just the lower most keyname) */
01094 
01095                 pstrcpy( name, ptr+1 );
01096         }
01097         else {
01098                 /* use the existing open key information */
01099                 newparentinfo = parent;
01100                 memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) );
01101         }
01102         
01103         /* (3) check for create subkey rights on the correct parent */
01104         
01105         if ( !(newparentinfo->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) {
01106                 result = WERR_ACCESS_DENIED;
01107                 goto done;
01108         }       
01109                 
01110         if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
01111                 result = WERR_NOMEM;
01112                 goto done;
01113         }
01114 
01115         /* (4) lookup the current keys and add the new one */
01116         
01117         fetch_reg_keys( newparentinfo, subkeys );
01118         regsubkey_ctr_addkey( subkeys, name );
01119         
01120         /* now write to the registry backend */
01121         
01122         write_result = store_reg_keys( newparentinfo, subkeys );
01123         
01124         TALLOC_FREE( subkeys );
01125 
01126         if ( !write_result )
01127                 return WERR_REG_IO_FAILURE;
01128                 
01129         /* (5) open the new key and return the handle.  Note that it is probably 
01130            not correct to grant full access on this open handle. */
01131         
01132         result = open_registry_key( p, &r_u->handle, &keyinfo, newparentinfo, name, REG_KEY_READ );
01133         keyinfo->access_granted = REG_KEY_ALL;
01134 
01135 done:
01136         /* close any intermediate key handles */
01137         
01138         if ( newparentinfo != parent )
01139                 close_registry_key( p, &newparent_handle );
01140                 
01141         return result;
01142 }
01143 
01144 
01145 /*******************************************************************
01146  ********************************************************************/
01147 
01148 WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE  *q_u, REG_R_SET_VALUE *r_u)
01149 {
01150         REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
01151         REGVAL_CTR *values;
01152         BOOL write_result;
01153         fstring valuename;
01154 
01155         if ( !key )
01156                 return WERR_BADFID;
01157                 
01158         /* access checks first */
01159         
01160         if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) )
01161                 return WERR_ACCESS_DENIED;
01162                 
01163         rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 );
01164 
01165         /* verify the name */
01166 
01167         if ( !*valuename )
01168                 return WERR_INVALID_PARAM;
01169 
01170         DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->name, valuename));
01171                 
01172         if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) )
01173                 return WERR_NOMEM; 
01174         
01175         /* lookup the current values and add the new one */
01176         
01177         fetch_reg_values( key, values );
01178         
01179         regval_ctr_addvalue( values, valuename, q_u->type, (char*)q_u->value.buffer, q_u->value.buf_len );
01180         
01181         /* now write to the registry backend */
01182         
01183         write_result = store_reg_values( key, values );
01184         
01185         TALLOC_FREE( values );
01186         
01187         if ( !write_result )
01188                 return WERR_REG_IO_FAILURE;
01189                 
01190         return WERR_OK;
01191 }
01192 
01193 /*******************************************************************
01194  ********************************************************************/
01195 
01196 WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY  *q_u, REG_R_DELETE_KEY *r_u)
01197 {
01198         REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
01199         REGISTRY_KEY *newparentinfo = NULL;
01200         POLICY_HND newparent_handle;
01201         REGSUBKEY_CTR *subkeys;
01202         BOOL write_result;
01203         pstring name;
01204         WERROR result;
01205 
01206         if ( !parent )
01207                 return WERR_BADFID;
01208 
01209         /* MSDN says parent the handle must have been opened with DELETE access */
01210 
01211         /* (1) check for delete rights on the parent */
01212         
01213         if ( !(parent->access_granted & STD_RIGHT_DELETE_ACCESS) ) {
01214                 result = WERR_ACCESS_DENIED;
01215                 goto done;
01216         }
01217                 
01218         rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
01219                 
01220         /* ok.  Here's what we do.  */
01221 
01222         if ( strrchr( name, '\\' ) ) {
01223                 pstring newkeyname;
01224                 char *ptr;
01225                 
01226                 /* (2) open the path to the child parent key if necessary */
01227                 /* split the registry path and save the subkeyname */
01228         
01229                 pstrcpy( newkeyname, name );
01230                 ptr = strrchr( newkeyname, '\\' );
01231                 *ptr = '\0';
01232                 pstrcpy( name, ptr+1 );
01233 
01234                 result = open_registry_key( p, &newparent_handle, &newparentinfo, parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) );
01235                 if ( !W_ERROR_IS_OK(result) )
01236                         return result;
01237         }
01238         else {
01239                 /* use the existing open key information */
01240                 newparentinfo = parent;
01241         }
01242         
01243         if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
01244                 result = WERR_NOMEM;
01245                 goto done;
01246         }
01247         
01248         /* lookup the current keys and delete the new one */
01249         
01250         fetch_reg_keys( newparentinfo, subkeys );
01251         
01252         regsubkey_ctr_delkey( subkeys, name );
01253         
01254         /* now write to the registry backend */
01255         
01256         write_result = store_reg_keys( newparentinfo, subkeys );
01257         
01258         TALLOC_FREE( subkeys );
01259 
01260         result = write_result ? WERR_OK : WERR_REG_IO_FAILURE;
01261         
01262 done:
01263         /* close any intermediate key handles */
01264         
01265         if ( newparentinfo != parent )
01266                 close_registry_key( p, &newparent_handle );
01267 
01268         return result;
01269 }
01270 
01271 
01272 /*******************************************************************
01273  ********************************************************************/
01274 
01275 WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE  *q_u, REG_R_DELETE_VALUE *r_u)
01276 {
01277         REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
01278         REGVAL_CTR *values;
01279         BOOL write_result;
01280         fstring valuename;
01281         
01282         if ( !key )
01283                 return WERR_BADFID;
01284                 
01285         /* access checks first */
01286         
01287         if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) )
01288                 return WERR_ACCESS_DENIED;
01289 
01290         rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 );
01291 
01292         if ( !*valuename )
01293                 return WERR_INVALID_PARAM;
01294 
01295         DEBUG(8,("_reg_delete_value: Setting value for [%s:%s]\n", key->name, valuename));
01296 
01297         if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) )
01298                 return WERR_NOMEM;
01299         
01300         /* lookup the current values and add the new one */
01301         
01302         fetch_reg_values( key, values );
01303         
01304         regval_ctr_delvalue( values, valuename );
01305         
01306         /* now write to the registry backend */
01307         
01308         write_result = store_reg_values( key, values );
01309         
01310         TALLOC_FREE( values );
01311         
01312         if ( !write_result )
01313                 return WERR_REG_IO_FAILURE;
01314                 
01315         return WERR_OK;
01316 }
01317 
01318 /*******************************************************************
01319  ********************************************************************/
01320 
01321 WERROR _reg_get_key_sec(pipes_struct *p, REG_Q_GET_KEY_SEC  *q_u, REG_R_GET_KEY_SEC *r_u)
01322 {
01323         REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
01324 
01325         if ( !key )
01326                 return WERR_BADFID;
01327                 
01328         /* access checks first */
01329         
01330         if ( !(key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
01331                 return WERR_ACCESS_DENIED;
01332                 
01333         return WERR_ACCESS_DENIED;
01334 }
01335 
01336 /*******************************************************************
01337  ********************************************************************/
01338 
01339 WERROR _reg_set_key_sec(pipes_struct *p, REG_Q_SET_KEY_SEC  *q_u, REG_R_SET_KEY_SEC *r_u)
01340 {
01341         REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
01342 
01343         if ( !key )
01344                 return WERR_BADFID;
01345                 
01346         /* access checks first */
01347         
01348         if ( !(key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
01349                 return WERR_ACCESS_DENIED;
01350                 
01351         return WERR_ACCESS_DENIED;
01352 }

Sambaに対してSat Aug 29 21:23:20 2009に生成されました。  doxygen 1.4.7