00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023
00024
00025
00026
00027 static TDB_CONTEXT *share_tdb;
00028 #define SHARE_DATABASE_VERSION_V1 1
00029 #define SHARE_DATABASE_VERSION_V2 2
00030
00031
00032
00033 static struct generic_mapping file_generic_mapping = {
00034 FILE_GENERIC_READ,
00035 FILE_GENERIC_WRITE,
00036 FILE_GENERIC_EXECUTE,
00037 FILE_GENERIC_ALL
00038 };
00039
00040
00041 BOOL share_info_db_init(void)
00042 {
00043 const char *vstring = "INFO/version";
00044 int32 vers_id;
00045
00046 if (share_tdb) {
00047 return True;
00048 }
00049
00050 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00051 if (!share_tdb) {
00052 DEBUG(0,("Failed to open share info database %s (%s)\n",
00053 lock_path("share_info.tdb"), strerror(errno) ));
00054 return False;
00055 }
00056
00057
00058 tdb_lock_bystring(share_tdb, vstring);
00059
00060
00061 vers_id = tdb_fetch_int32(share_tdb, vstring);
00062 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
00063
00064 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
00065 vers_id = SHARE_DATABASE_VERSION_V2;
00066 }
00067
00068 if (vers_id != SHARE_DATABASE_VERSION_V2) {
00069 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
00070 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
00071 }
00072 tdb_unlock_bystring(share_tdb, vstring);
00073
00074 return True;
00075 }
00076
00077
00078
00079
00080
00081
00082 SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def_access)
00083 {
00084 SEC_ACCESS sa;
00085 SEC_ACE ace;
00086 SEC_ACL *psa = NULL;
00087 SEC_DESC *psd = NULL;
00088 uint32 spec_access = def_access;
00089
00090 se_map_generic(&spec_access, &file_generic_mapping);
00091
00092 init_sec_access(&sa, def_access | spec_access );
00093 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
00094
00095 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
00096 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize);
00097 }
00098
00099 if (!psd) {
00100 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
00101 return NULL;
00102 }
00103
00104 return psd;
00105 }
00106
00107
00108
00109
00110
00111 SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename,
00112 size_t *psize)
00113 {
00114 prs_struct ps;
00115 fstring key;
00116 SEC_DESC *psd = NULL;
00117
00118 if (!share_info_db_init()) {
00119 return NULL;
00120 }
00121
00122 *psize = 0;
00123
00124
00125
00126 slprintf(key, sizeof(key)-1, "SECDESC/%s", servicename);
00127
00128 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
00129 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
00130
00131 DEBUG(4, ("get_share_security: using default secdesc for %s\n",
00132 servicename));
00133
00134 return get_share_security_default(ctx, psize, GENERIC_ALL_ACCESS);
00135 }
00136
00137 if (psd)
00138 *psize = sec_desc_size(psd);
00139
00140 prs_mem_free(&ps);
00141 return psd;
00142 }
00143
00144
00145
00146
00147
00148 BOOL set_share_security(const char *share_name, SEC_DESC *psd)
00149 {
00150 prs_struct ps;
00151 TALLOC_CTX *mem_ctx = NULL;
00152 fstring key;
00153 BOOL ret = False;
00154
00155 if (!share_info_db_init()) {
00156 return False;
00157 }
00158
00159 mem_ctx = talloc_init("set_share_security");
00160 if (mem_ctx == NULL)
00161 return False;
00162
00163 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
00164
00165 if (!sec_io_desc("share_security", &psd, &ps, 1))
00166 goto out;
00167
00168 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
00169
00170 if (tdb_prs_store(share_tdb, key, &ps)==0) {
00171 ret = True;
00172 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
00173 } else {
00174 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
00175 }
00176
00177
00178
00179 out:
00180
00181 prs_mem_free(&ps);
00182 if (mem_ctx)
00183 talloc_destroy(mem_ctx);
00184 return ret;
00185 }
00186
00187
00188
00189
00190
00191 BOOL delete_share_security(const struct share_params *params)
00192 {
00193 TDB_DATA kbuf;
00194 fstring key;
00195
00196 slprintf(key, sizeof(key)-1, "SECDESC/%s",
00197 lp_servicename(params->service));
00198 kbuf.dptr = key;
00199 kbuf.dsize = strlen(key)+1;
00200
00201 if (tdb_trans_delete(share_tdb, kbuf) != 0) {
00202 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
00203 lp_servicename(params->service) ));
00204 return False;
00205 }
00206
00207 return True;
00208 }
00209
00210
00211
00212
00213
00214 BOOL share_access_check(const NT_USER_TOKEN *token, const char *sharename,
00215 uint32 desired_access)
00216 {
00217 uint32 granted;
00218 NTSTATUS status;
00219 TALLOC_CTX *mem_ctx = NULL;
00220 SEC_DESC *psd = NULL;
00221 size_t sd_size;
00222 BOOL ret = True;
00223
00224 if (!(mem_ctx = talloc_init("share_access_check"))) {
00225 return False;
00226 }
00227
00228 psd = get_share_security(mem_ctx, sharename, &sd_size);
00229
00230 if (!psd) {
00231 TALLOC_FREE(mem_ctx);
00232 return True;
00233 }
00234
00235 ret = se_access_check(psd, token, desired_access, &granted, &status);
00236
00237 talloc_destroy(mem_ctx);
00238 return ret;
00239 }
00240
00241
00242
00243
00244
00245 BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
00246 {
00247 size_t s_size = 0;
00248 const char *pacl = acl_str;
00249 int num_aces = 0;
00250 SEC_ACE *ace_list = NULL;
00251 SEC_ACL *psa = NULL;
00252 SEC_DESC *psd = NULL;
00253 size_t sd_size = 0;
00254 int i;
00255
00256 *ppsd = NULL;
00257
00258
00259 if (!*acl_str) {
00260 SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
00261 if (!default_psd) {
00262 return False;
00263 }
00264 *ppsd = default_psd;
00265 return True;
00266 }
00267
00268 num_aces = 1;
00269
00270
00271 num_aces += count_chars(pacl,',');
00272
00273 ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
00274 if (!ace_list) {
00275 return False;
00276 }
00277
00278 for (i = 0; i < num_aces; i++) {
00279 SEC_ACCESS sa;
00280 uint32 g_access;
00281 uint32 s_access;
00282 DOM_SID sid;
00283 fstring sidstr;
00284 uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED;
00285
00286 if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) {
00287 DEBUG(0,("parse_usershare_acl: malformed usershare acl looking "
00288 "for ':' in string '%s'\n", pacl));
00289 return False;
00290 }
00291
00292 if (!string_to_sid(&sid, sidstr)) {
00293 DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n",
00294 sidstr ));
00295 return False;
00296 }
00297
00298 switch (*pacl) {
00299 case 'F':
00300 case 'f':
00301 s_access = g_access = GENERIC_ALL_ACCESS;
00302 break;
00303 case 'R':
00304 case 'r':
00305 s_access = g_access = GENERIC_READ_ACCESS;
00306 break;
00307 case 'D':
00308 case 'd':
00309 type = SEC_ACE_TYPE_ACCESS_DENIED;
00310 s_access = g_access = GENERIC_ALL_ACCESS;
00311 break;
00312 default:
00313 DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n",
00314 pacl ));
00315 return False;
00316 }
00317
00318 pacl++;
00319 if (*pacl && *pacl != ',') {
00320 DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n",
00321 pacl ));
00322 return False;
00323 }
00324 pacl++;
00325
00326 se_map_generic(&s_access, &file_generic_mapping);
00327 init_sec_access(&sa, g_access | s_access );
00328 init_sec_ace(&ace_list[i], &sid, type, sa, 0);
00329 }
00330
00331 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) {
00332 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size);
00333 }
00334
00335 if (!psd) {
00336 DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n"));
00337 return False;
00338 }
00339
00340 *ppsd = psd;
00341 return True;
00342 }