r22484: Check for the talloc_strdup to succeed.
[sfrench/samba-autobuild/.git] / source / libgpo / gpo_fetch.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Guenther Deschner 2005-2006
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 2 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, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23 /****************************************************************
24  explode the GPO CIFS URI into their components
25 ****************************************************************/
26
27 NTSTATUS ads_gpo_explode_filesyspath(ADS_STRUCT *ads, 
28                                      TALLOC_CTX *mem_ctx, 
29                                      const char *file_sys_path, 
30                                      char **server, 
31                                      char **service, 
32                                      char **nt_path,
33                                      char **unix_path)
34 {
35         fstring tok;
36         pstring path;
37
38         *server = NULL;
39         *service = NULL;
40         *nt_path = NULL;
41         *unix_path = NULL;
42
43         if (!next_token(&file_sys_path, tok, "\\", sizeof(tok))) {
44                 return NT_STATUS_INVALID_PARAMETER;
45         }
46
47         if ((*server = talloc_strdup(mem_ctx, tok)) == NULL) {
48                 return NT_STATUS_NO_MEMORY;
49         }
50
51         if (!next_token(&file_sys_path, tok, "\\", sizeof(tok))) {
52                 return NT_STATUS_INVALID_PARAMETER;
53         }
54
55         if ((*service = talloc_strdup(mem_ctx, tok)) == NULL) {
56                 return NT_STATUS_NO_MEMORY;
57         }
58
59         if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path)) == NULL) {
60                 return NT_STATUS_NO_MEMORY;
61         }
62
63         pstrcpy(path, lock_path(GPO_CACHE_DIR));
64         pstrcat(path, "/");
65         pstrcat(path, file_sys_path);
66         pstring_sub(path, "\\", "/");
67
68         if ((*unix_path = talloc_strdup(mem_ctx, path)) == NULL) {
69                 return NT_STATUS_NO_MEMORY;
70         }
71
72         return NT_STATUS_OK;
73 }
74
75 /****************************************************************
76  prepare the local disc storage for "unix_path"
77 ****************************************************************/
78
79 NTSTATUS ads_gpo_prepare_local_store(ADS_STRUCT *ads, 
80                                      TALLOC_CTX *mem_ctx, 
81                                      const char *unix_path)
82 {
83         const char *top_dir = lock_path(GPO_CACHE_DIR);
84         char *current_dir;
85         fstring tok;
86
87         current_dir = talloc_strdup(mem_ctx, top_dir);
88         NT_STATUS_HAVE_NO_MEMORY(current_dir);
89
90         if ((mkdir(top_dir, 0644)) < 0 && errno != EEXIST) {
91                 return NT_STATUS_ACCESS_DENIED;
92         }
93
94         while (next_token(&unix_path, tok, "/", sizeof(tok))) {
95         
96                 if (strequal(tok, GPO_CACHE_DIR)) {
97                         break;
98                 }
99         }
100
101         while (next_token(&unix_path, tok, "/", sizeof(tok))) {
102
103                 current_dir = talloc_asprintf_append(current_dir, "/%s", tok);
104                 NT_STATUS_HAVE_NO_MEMORY(current_dir);
105
106                 if ((mkdir(current_dir, 0644)) < 0 && errno != EEXIST) {
107                         return NT_STATUS_ACCESS_DENIED;
108                 }
109         }
110
111         return NT_STATUS_OK;
112 }
113
114 /****************************************************************
115  download a full GPO via CIFS
116 ****************************************************************/
117
118 NTSTATUS ads_fetch_gpo_files(ADS_STRUCT *ads, 
119                             TALLOC_CTX *mem_ctx, 
120                             struct cli_state *cli, 
121                             struct GROUP_POLICY_OBJECT *gpo)
122 {
123         NTSTATUS result;
124         char *server, *service, *nt_path, *unix_path, *nt_ini_path, *unix_ini_path;
125
126         result = ads_gpo_explode_filesyspath(ads, mem_ctx, gpo->file_sys_path, 
127                                              &server, &service, &nt_path, &unix_path);
128         if (!NT_STATUS_IS_OK(result)) {
129                 goto out;
130         }
131
132         result = ads_gpo_prepare_local_store(ads, mem_ctx, unix_path);
133         if (!NT_STATUS_IS_OK(result)) {
134                 goto out;
135         }
136
137         unix_ini_path = talloc_asprintf(mem_ctx, "%s/%s", unix_path, GPT_INI);
138         nt_ini_path = talloc_asprintf(mem_ctx, "%s\\%s", nt_path, GPT_INI);
139         if (!unix_path || !nt_ini_path) {
140                 result = NT_STATUS_NO_MEMORY;
141                 goto out;
142         }
143
144         result = gpo_copy_file(mem_ctx, cli, nt_ini_path, unix_ini_path);
145         if (!NT_STATUS_IS_OK(result)) {
146                 goto out;
147         }
148
149         result = gpo_sync_directories(mem_ctx, cli, nt_path, unix_path);
150         if (!NT_STATUS_IS_OK(result)) {
151                 goto out;
152         }
153
154         result = NT_STATUS_OK;
155
156  out:
157         return result;
158 }
159
160 /****************************************************************
161  get the locally stored gpt.ini version number
162 ****************************************************************/
163
164 NTSTATUS ads_gpo_get_sysvol_gpt_version(ADS_STRUCT *ads, 
165                                         TALLOC_CTX *mem_ctx, 
166                                         const char *unix_path, 
167                                         uint32 *sysvol_version,
168                                         char **display_name)
169 {
170         NTSTATUS status;
171         uint32 version;
172         char *local_path = NULL;
173         char *name = NULL;
174
175         local_path = talloc_asprintf(mem_ctx, "%s/%s", unix_path, GPT_INI);
176         NT_STATUS_HAVE_NO_MEMORY(local_path);
177
178         status = parse_gpt_ini(mem_ctx, local_path, &version, &name);
179         if (!NT_STATUS_IS_OK(status)) {
180                 DEBUG(10,("ads_gpo_get_sysvol_gpt_version: failed to parse ini [%s]: %s\n", 
181                         unix_path, nt_errstr(status)));
182                 return status;
183         }
184
185         if (sysvol_version) {
186                 *sysvol_version = version;
187         }
188
189         if (name && *display_name) {
190                 *display_name = talloc_strdup(mem_ctx, name);
191                 NT_STATUS_HAVE_NO_MEMORY(*display_name);
192         }
193
194         return NT_STATUS_OK;
195 }