root/source4/lib/registry/dir.c

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

DEFINITIONS

This source file includes following definitions.
  1. reg_dir_add_key
  2. reg_dir_delete_recursive
  3. reg_dir_del_key
  4. reg_dir_open_key
  5. reg_dir_key_by_index
  6. reg_open_directory
  7. reg_create_directory
  8. reg_dir_get_info
  9. reg_dir_set_value
  10. reg_dir_get_value
  11. reg_dir_enum_value
  12. reg_dir_del_value

   1 /*
   2    Unix SMB/CIFS implementation.
   3    Registry interface
   4    Copyright (C) Jelmer Vernooij                                  2004-2007.
   5 
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10 
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15 
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "registry.h"
  22 #include "system/dir.h"
  23 #include "system/filesys.h"
  24 
  25 struct dir_key {
  26         struct hive_key key;
  27         const char *path;
  28 };
  29 
  30 static struct hive_operations reg_backend_dir;
  31 
  32 static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  33                               const struct hive_key *parent,
  34                               const char *name, const char *classname,
  35                               struct security_descriptor *desc,
  36                               struct hive_key **result)
  37 {
  38         struct dir_key *dk = talloc_get_type(parent, struct dir_key);
  39         char *path;
  40         int ret;
  41 
  42         path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
  43         ret = mkdir(path, 0700);
  44         if (ret == 0) {
  45                 struct dir_key *key = talloc(mem_ctx, struct dir_key);
  46                 key->key.ops = &reg_backend_dir;
  47                 key->path = talloc_steal(key, path);
  48                 *result = (struct hive_key *)key;
  49                 return WERR_OK;
  50         }
  51 
  52         if (errno == EEXIST)
  53                 return WERR_ALREADY_EXISTS;
  54         printf("FAILED %s BECAUSE: %s\n", path, strerror(errno));
  55         return WERR_GENERAL_FAILURE;
  56 }
  57 
  58 static WERROR reg_dir_delete_recursive(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60         DIR *d;
  61         struct dirent *e;
  62         WERROR werr;
  63 
  64         d = opendir(name);
  65         if (d == NULL) {
  66                 DEBUG(3,("Unable to open '%s': %s\n", name,
  67                       strerror(errno)));
  68                 return WERR_BADFILE;
  69         }
  70 
  71         while((e = readdir(d))) {
  72                 char *path;
  73                 struct stat stbuf;
  74 
  75                 if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
  76                         continue;
  77 
  78                 path = talloc_asprintf(name, "%s/%s", name, e->d_name);
  79                 if (!path)
  80                         return WERR_NOMEM;
  81 
  82                 stat(path, &stbuf);
  83 
  84                 if (!S_ISDIR(stbuf.st_mode)) {
  85                         if (unlink(path) < 0) {
  86                                 talloc_free(path);
  87                                 closedir(d);
  88                                 return WERR_GENERAL_FAILURE;
  89                         }
  90                 } else {
  91                         werr = reg_dir_delete_recursive(path);
  92                         if (!W_ERROR_IS_OK(werr)) {
  93                                 talloc_free(path);
  94                                 closedir(d);
  95                                 return werr;
  96                         }
  97                 }
  98 
  99                 talloc_free(path);
 100         }
 101         closedir(d);
 102 
 103         if (rmdir(name) == 0)
 104                 return WERR_OK;
 105         else if (errno == ENOENT)
 106                 return WERR_BADFILE;
 107         else
 108                 return WERR_GENERAL_FAILURE;
 109 }
 110 
 111 static WERROR reg_dir_del_key(const struct hive_key *k, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 112 {
 113         struct dir_key *dk = talloc_get_type(k, struct dir_key);
 114         char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);
 115         WERROR ret;
 116 
 117         ret = reg_dir_delete_recursive(child);
 118 
 119         talloc_free(child);
 120 
 121         return ret;
 122 }
 123 
 124 static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 125                                const struct hive_key *parent,
 126                                const char *name, struct hive_key **subkey)
 127 {
 128         DIR *d;
 129         char *fullpath;
 130         const struct dir_key *p = talloc_get_type(parent, struct dir_key);
 131         struct dir_key *ret;
 132 
 133         if (name == NULL) {
 134                 DEBUG(0, ("NULL pointer passed as directory name!"));
 135                 return WERR_INVALID_PARAM;
 136         }
 137 
 138         fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name);
 139 
 140         d = opendir(fullpath);
 141         if (d == NULL) {
 142                 DEBUG(3,("Unable to open '%s': %s\n", fullpath,
 143                         strerror(errno)));
 144                 return WERR_BADFILE;
 145         }
 146         closedir(d);
 147         ret = talloc(mem_ctx, struct dir_key);
 148         ret->key.ops = &reg_backend_dir;
 149         ret->path = talloc_steal(ret, fullpath);
 150         *subkey = (struct hive_key *)ret;
 151         return WERR_OK;
 152 }
 153 
 154 static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 155                                    const struct hive_key *k, uint32_t idx,
 156                                    const char **name,
 157                                    const char **classname,
 158                                    NTTIME *last_mod_time)
 159 {
 160         struct dirent *e;
 161         const struct dir_key *dk = talloc_get_type(k, struct dir_key);
 162         int i = 0;
 163         DIR *d;
 164 
 165         d = opendir(dk->path);
 166 
 167         if (d == NULL)
 168                 return WERR_INVALID_PARAM;
 169 
 170         while((e = readdir(d))) {
 171                 if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {
 172                         struct stat stbuf;
 173                         char *thispath;
 174 
 175                         /* Check if file is a directory */
 176                         asprintf(&thispath, "%s/%s", dk->path, e->d_name);
 177                         stat(thispath, &stbuf);
 178 
 179                         if (!S_ISDIR(stbuf.st_mode)) {
 180                                 SAFE_FREE(thispath);
 181                                 continue;
 182                         }
 183 
 184                         if (i == idx) {
 185                                 struct stat st;
 186                                 *name = talloc_strdup(mem_ctx, e->d_name);
 187                                 *classname = NULL;
 188                                 stat(thispath, &st);
 189                                 unix_to_nt_time(last_mod_time, st.st_mtime);
 190                                 SAFE_FREE(thispath);
 191                                 closedir(d);
 192                                 return WERR_OK;
 193                         }
 194                         i++;
 195 
 196                         SAFE_FREE(thispath);
 197                 }
 198         }
 199 
 200         closedir(d);
 201 
 202         return WERR_NO_MORE_ITEMS;
 203 }
 204 
 205 WERROR reg_open_directory(TALLOC_CTX *parent_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 206                           const char *location, struct hive_key **key)
 207 {
 208         struct dir_key *dk;
 209 
 210         if (location == NULL)
 211                 return WERR_INVALID_PARAM;
 212 
 213         dk = talloc(parent_ctx, struct dir_key);
 214         dk->key.ops = &reg_backend_dir;
 215         dk->path = talloc_strdup(dk, location);
 216         *key = (struct hive_key *)dk;
 217         return WERR_OK;
 218 }
 219 
 220 WERROR reg_create_directory(TALLOC_CTX *parent_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 221                             const char *location, struct hive_key **key)
 222 {
 223         if (mkdir(location, 0700) != 0) {
 224                 *key = NULL;
 225                 return WERR_GENERAL_FAILURE;
 226         }
 227 
 228         return reg_open_directory(parent_ctx, location, key);
 229 }
 230 
 231 static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key,
     /* [<][>][^][v][top][bottom][index][help] */
 232                                const char **classname,
 233                                uint32_t *num_subkeys,
 234                                uint32_t *num_values,
 235                                NTTIME *lastmod,
 236                                uint32_t *max_subkeynamelen,
 237                                uint32_t *max_valnamelen,
 238                                uint32_t *max_valbufsize)
 239 {
 240         DIR *d;
 241         const struct dir_key *dk = talloc_get_type(key, struct dir_key);
 242         struct dirent *e;
 243         struct stat st;
 244 
 245         SMB_ASSERT(key != NULL);
 246 
 247         if (classname != NULL)
 248                 *classname = NULL;
 249 
 250         d = opendir(dk->path);
 251         if (d == NULL)
 252                 return WERR_INVALID_PARAM;
 253 
 254         if (num_subkeys != NULL)
 255                 *num_subkeys = 0;
 256 
 257         if (num_values != NULL)
 258                 *num_values = 0;
 259 
 260         if (max_subkeynamelen != NULL)
 261                 *max_subkeynamelen = 0;
 262 
 263         if (max_valnamelen != NULL)
 264                 *max_valnamelen = 0;
 265 
 266         if (max_valbufsize != NULL)
 267                 *max_valbufsize = 0;
 268 
 269         while((e = readdir(d))) {
 270                 if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) {
 271                         char *path = talloc_asprintf(ctx, "%s/%s",
 272                                                      dk->path, e->d_name);
 273 
 274                         if (stat(path, &st) < 0) {
 275                                 DEBUG(0, ("Error statting %s: %s\n", path,
 276                                         strerror(errno)));
 277                                 continue;
 278                         }
 279 
 280                         if (S_ISDIR(st.st_mode)) {
 281                                 if (num_subkeys != NULL)
 282                                         (*num_subkeys)++;
 283                                 if (max_subkeynamelen != NULL)
 284                                         *max_subkeynamelen = MAX(*max_subkeynamelen, strlen(e->d_name));
 285                         }
 286 
 287                         if (!S_ISDIR(st.st_mode)) {
 288                                 if (num_values != NULL)
 289                                         (*num_values)++;
 290                                 if (max_valnamelen != NULL)
 291                                         *max_valnamelen = MAX(*max_valnamelen, strlen(e->d_name));
 292                                 if (max_valbufsize != NULL)
 293                                         *max_valbufsize = MAX(*max_valbufsize, st.st_size);
 294                         }
 295 
 296                         talloc_free(path);
 297                 }
 298         }
 299 
 300         closedir(d);
 301 
 302         if (lastmod != NULL)
 303                 *lastmod = 0;
 304         return WERR_OK;
 305 }
 306 
 307 static WERROR reg_dir_set_value(struct hive_key *key, const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
 308                                 uint32_t type, const DATA_BLOB data)
 309 {
 310         const struct dir_key *dk = talloc_get_type(key, struct dir_key);
 311         char *path = talloc_asprintf(dk, "%s/%s", dk->path, name);
 312 
 313         if (!file_save(path, data.data, data.length))
 314                 return WERR_GENERAL_FAILURE;
 315 
 316         /* FIXME: Type */
 317 
 318         return WERR_OK;
 319 }
 320 
 321 static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 322                                 struct hive_key *key, const char *name,
 323                                 uint32_t *type, DATA_BLOB *data)
 324 {
 325         const struct dir_key *dk = talloc_get_type(key, struct dir_key);
 326         char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name);
 327         size_t size;
 328         char *contents;
 329 
 330         contents = file_load(path, &size, 0, mem_ctx);
 331         talloc_free(path);
 332         if (contents == NULL)
 333                 return WERR_BADFILE;
 334 
 335         if (type != NULL)
 336                 *type = 4; /* FIXME */
 337 
 338         data->data = (uint8_t *)contents;
 339         data->length = size;
 340 
 341         return WERR_OK;
 342 }
 343 
 344 static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 345                                  struct hive_key *key, int idx,
 346                                  const char **name,
 347                                  uint32_t *type, DATA_BLOB *data)
 348 {
 349         const struct dir_key *dk = talloc_get_type(key, struct dir_key);
 350         DIR *d;
 351         struct dirent *e;
 352         int i;
 353 
 354         d = opendir(dk->path);
 355         if (d == NULL) {
 356                 DEBUG(3,("Unable to open '%s': %s\n", dk->path,
 357                         strerror(errno)));
 358                 return WERR_BADFILE;
 359         }
 360 
 361         i = 0;
 362         while((e = readdir(d))) {
 363                 if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
 364                         continue;
 365 
 366                 if (i == idx) {
 367                         if (name != NULL)
 368                                 *name = talloc_strdup(mem_ctx, e->d_name);
 369                         W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key,
 370                                                                 *name, type,
 371                                                                 data));
 372                         return WERR_OK;
 373                 }
 374 
 375                 i++;
 376         }
 377         closedir(d);
 378 
 379         return WERR_NO_MORE_ITEMS;
 380 }
 381 
 382 
 383 static WERROR reg_dir_del_value (struct hive_key *key, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 384 {
 385         const struct dir_key *dk = talloc_get_type(key, struct dir_key);
 386         char *path = talloc_asprintf(key, "%s/%s", dk->path, name);
 387         if (unlink(path) < 0) {
 388                 talloc_free(path);
 389                 if (errno == ENOENT)
 390                         return WERR_BADFILE;
 391                 return WERR_GENERAL_FAILURE;
 392         }
 393         talloc_free(path);
 394 
 395         return WERR_OK;
 396 }
 397 
 398 static struct hive_operations reg_backend_dir = {
 399         .name = "dir",
 400         .get_key_by_name = reg_dir_open_key,
 401         .get_key_info = reg_dir_get_info,
 402         .add_key = reg_dir_add_key,
 403         .del_key = reg_dir_del_key,
 404         .enum_key = reg_dir_key_by_index,
 405         .set_value = reg_dir_set_value,
 406         .get_value_by_name = reg_dir_get_value,
 407         .enum_value = reg_dir_enum_value,
 408         .delete_value = reg_dir_del_value,
 409 };

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