1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.security.access;
19
20 import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.util.List;
25 import java.util.Arrays;
26 import java.util.Map;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HColumnDescriptor;
33 import org.apache.hadoop.hbase.HConstants;
34 import org.apache.hadoop.hbase.HTableDescriptor;
35 import org.apache.hadoop.hbase.NamespaceDescriptor;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.testclassification.MediumTests;
38 import org.apache.hadoop.hbase.TableName;
39 import org.apache.hadoop.hbase.client.Get;
40 import org.apache.hadoop.hbase.client.HBaseAdmin;
41 import org.apache.hadoop.hbase.client.Result;
42 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
43 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
44 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
45 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
46 import org.apache.hadoop.hbase.security.User;
47 import org.apache.hadoop.hbase.security.access.Permission.Action;
48 import org.apache.hadoop.hbase.util.Bytes;
49 import org.junit.AfterClass;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53
54 import com.google.common.collect.ListMultimap;
55 import com.google.protobuf.BlockingRpcChannel;
56
57 @Category(MediumTests.class)
58 public class TestNamespaceCommands extends SecureTestUtil {
59 private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
60 private static final Log LOG = LogFactory.getLog(TestNamespaceCommands.class);
61 private static String TEST_NAMESPACE = "ns1";
62 private static String TEST_NAMESPACE2 = "ns2";
63 private static Configuration conf;
64 private static MasterCoprocessorEnvironment CP_ENV;
65 private static AccessController ACCESS_CONTROLLER;
66
67
68 private static User SUPERUSER;
69
70
71 private static User USER_GLOBAL_ADMIN;
72
73 private static User USER_GLOBAL_CREATE;
74
75 private static User USER_GLOBAL_WRITE;
76
77 private static User USER_GLOBAL_READ;
78
79 private static User USER_GLOBAL_EXEC;
80
81
82 private static User USER_NS_ADMIN;
83
84 private static User USER_NS_CREATE;
85
86 private static User USER_NS_WRITE;
87
88 private static User USER_NS_READ;
89
90 private static User USER_NS_EXEC;
91
92
93 private static User USER_TABLE_WRITE;
94
95 private static User USER_TABLE_CREATE;
96
97 private static final String GROUP_ADMIN = "group_admin";
98 private static final String GROUP_NS_ADMIN = "group_ns_admin";
99 private static final String GROUP_CREATE = "group_create";
100 private static final String GROUP_READ = "group_read";
101 private static final String GROUP_WRITE = "group_write";
102
103 private static User USER_GROUP_ADMIN;
104 private static User USER_GROUP_NS_ADMIN;
105 private static User USER_GROUP_CREATE;
106 private static User USER_GROUP_READ;
107 private static User USER_GROUP_WRITE;
108
109 private static String TEST_TABLE = TEST_NAMESPACE + ":testtable";
110 private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
111
112 @BeforeClass
113 public static void beforeClass() throws Exception {
114 conf = UTIL.getConfiguration();
115 enableSecurity(conf);
116
117 SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
118
119 USER_GLOBAL_ADMIN = User.createUserForTesting(conf, "global_admin", new String[0]);
120 USER_GLOBAL_CREATE = User.createUserForTesting(conf, "global_create", new String[0]);
121 USER_GLOBAL_WRITE = User.createUserForTesting(conf, "global_write", new String[0]);
122 USER_GLOBAL_READ = User.createUserForTesting(conf, "global_read", new String[0]);
123 USER_GLOBAL_EXEC = User.createUserForTesting(conf, "global_exec", new String[0]);
124
125 USER_NS_ADMIN = User.createUserForTesting(conf, "namespace_admin", new String[0]);
126 USER_NS_CREATE = User.createUserForTesting(conf, "namespace_create", new String[0]);
127 USER_NS_WRITE = User.createUserForTesting(conf, "namespace_write", new String[0]);
128 USER_NS_READ = User.createUserForTesting(conf, "namespace_read", new String[0]);
129 USER_NS_EXEC = User.createUserForTesting(conf, "namespace_exec", new String[0]);
130
131 USER_TABLE_CREATE = User.createUserForTesting(conf, "table_create", new String[0]);
132 USER_TABLE_WRITE = User.createUserForTesting(conf, "table_write", new String[0]);
133
134
135 USER_GROUP_ADMIN =
136 User.createUserForTesting(conf, "user_group_admin", new String[] { GROUP_ADMIN });
137 USER_GROUP_NS_ADMIN =
138 User.createUserForTesting(conf, "user_group_ns_admin", new String[] { GROUP_NS_ADMIN });
139 USER_GROUP_CREATE =
140 User.createUserForTesting(conf, "user_group_create", new String[] { GROUP_CREATE });
141 USER_GROUP_READ =
142 User.createUserForTesting(conf, "user_group_read", new String[] { GROUP_READ });
143 USER_GROUP_WRITE =
144 User.createUserForTesting(conf, "user_group_write", new String[] { GROUP_WRITE });
145
146 UTIL.startMiniCluster();
147
148 UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME.getName(), 30 * 1000);
149
150 ACCESS_CONTROLLER = (AccessController) UTIL.getMiniHBaseCluster().getMaster()
151 .getCoprocessorHost()
152 .findCoprocessor(AccessController.class.getName());
153
154 UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE).build());
155 UTIL.getHBaseAdmin().createNamespace(NamespaceDescriptor.create(TEST_NAMESPACE2).build());
156
157
158 grantGlobal(UTIL, USER_GLOBAL_ADMIN.getShortName(), Permission.Action.ADMIN);
159 grantGlobal(UTIL, USER_GLOBAL_CREATE.getShortName(), Permission.Action.CREATE);
160 grantGlobal(UTIL, USER_GLOBAL_WRITE.getShortName(), Permission.Action.WRITE);
161 grantGlobal(UTIL, USER_GLOBAL_READ.getShortName(), Permission.Action.READ);
162 grantGlobal(UTIL, USER_GLOBAL_EXEC.getShortName(), Permission.Action.EXEC);
163
164 grantGlobal(UTIL, toGroupEntry(GROUP_ADMIN), Permission.Action.ADMIN);
165 grantGlobal(UTIL, toGroupEntry(GROUP_CREATE), Permission.Action.CREATE);
166 grantGlobal(UTIL, toGroupEntry(GROUP_READ), Permission.Action.READ);
167 grantGlobal(UTIL, toGroupEntry(GROUP_WRITE), Permission.Action.WRITE);
168
169
170 grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE, Permission.Action.ADMIN);
171 grantOnNamespace(UTIL, USER_NS_CREATE.getShortName(), TEST_NAMESPACE, Permission.Action.CREATE);
172 grantOnNamespace(UTIL, USER_NS_WRITE.getShortName(), TEST_NAMESPACE, Permission.Action.WRITE);
173 grantOnNamespace(UTIL, USER_NS_READ.getShortName(), TEST_NAMESPACE, Permission.Action.READ);
174 grantOnNamespace(UTIL, USER_NS_EXEC.getShortName(), TEST_NAMESPACE, Permission.Action.EXEC);
175
176 grantOnNamespace(UTIL, USER_NS_ADMIN.getShortName(), TEST_NAMESPACE2, Permission.Action.ADMIN);
177 grantOnNamespace(UTIL, toGroupEntry(GROUP_NS_ADMIN), TEST_NAMESPACE, Permission.Action.ADMIN);
178 }
179
180 @AfterClass
181 public static void afterClass() throws Exception {
182 UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE);
183 UTIL.getHBaseAdmin().deleteNamespace(TEST_NAMESPACE2);
184 UTIL.shutdownMiniCluster();
185 }
186
187 @Test
188 public void testAclTableEntries() throws Exception {
189 String userTestNamespace = "userTestNsp";
190 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
191 try {
192 ListMultimap<String, TablePermission> perms =
193 AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
194
195 perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
196 for (Map.Entry<String, TablePermission> entry : perms.entries()) {
197 LOG.debug(entry);
198 }
199 assertEquals(6, perms.size());
200
201
202 grantOnNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
203 Permission.Action.WRITE);
204
205 Result result = acl.get(new Get(Bytes.toBytes(userTestNamespace)));
206 assertTrue(result != null);
207 perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
208 assertEquals(7, perms.size());
209 List<TablePermission> namespacePerms = perms.get(userTestNamespace);
210 assertTrue(perms.containsKey(userTestNamespace));
211 assertEquals(1, namespacePerms.size());
212 assertEquals(TEST_NAMESPACE,
213 namespacePerms.get(0).getNamespace());
214 assertEquals(null, namespacePerms.get(0).getFamily());
215 assertEquals(null, namespacePerms.get(0).getQualifier());
216 assertEquals(1, namespacePerms.get(0).getActions().length);
217 assertEquals(Permission.Action.WRITE, namespacePerms.get(0).getActions()[0]);
218
219
220 revokeFromNamespace(UTIL, userTestNamespace, TEST_NAMESPACE,
221 Permission.Action.WRITE);
222
223 perms = AccessControlLists.getNamespacePermissions(conf, TEST_NAMESPACE);
224 assertEquals(6, perms.size());
225 } finally {
226 acl.close();
227 }
228 }
229
230 @Test
231 public void testModifyNamespace() throws Exception {
232 AccessTestAction modifyNamespace = new AccessTestAction() {
233 public Object run() throws Exception {
234 ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
235 NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build());
236 return null;
237 }
238 };
239
240
241 verifyAllowed(modifyNamespace,
242 SUPERUSER,
243 USER_GLOBAL_ADMIN);
244
245 verifyDenied(modifyNamespace,
246 USER_GLOBAL_CREATE,
247 USER_GLOBAL_WRITE,
248 USER_GLOBAL_READ,
249 USER_GLOBAL_EXEC,
250 USER_NS_ADMIN,
251 USER_NS_CREATE,
252 USER_NS_WRITE,
253 USER_NS_READ,
254 USER_NS_EXEC);
255 }
256
257 @Test
258 public void testCreateAndDeleteNamespace() throws Exception {
259 AccessTestAction createNamespace = new AccessTestAction() {
260 @Override
261 public Object run() throws Exception {
262 ACCESS_CONTROLLER.preCreateNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
263 NamespaceDescriptor.create(TEST_NAMESPACE2).build());
264 return null;
265 }
266 };
267
268 AccessTestAction deleteNamespace = new AccessTestAction() {
269 @Override
270 public Object run() throws Exception {
271 ACCESS_CONTROLLER.preDeleteNamespace(ObserverContext.createAndPrepare(CP_ENV, null),
272 TEST_NAMESPACE2);
273 return null;
274 }
275 };
276
277
278 verifyAllowed(createNamespace,
279 SUPERUSER,
280 USER_GLOBAL_ADMIN);
281
282
283 verifyDenied(createNamespace,
284 USER_GLOBAL_CREATE,
285 USER_GLOBAL_WRITE,
286 USER_GLOBAL_READ,
287 USER_GLOBAL_EXEC,
288 USER_NS_ADMIN,
289 USER_NS_CREATE,
290 USER_NS_WRITE,
291 USER_NS_READ,
292 USER_NS_EXEC,
293 USER_TABLE_CREATE,
294 USER_TABLE_WRITE);
295
296
297 verifyAllowed(deleteNamespace,
298 SUPERUSER,
299 USER_GLOBAL_ADMIN);
300
301 verifyDenied(deleteNamespace,
302 USER_GLOBAL_CREATE,
303 USER_GLOBAL_WRITE,
304 USER_GLOBAL_READ,
305 USER_GLOBAL_EXEC,
306 USER_NS_ADMIN,
307 USER_NS_CREATE,
308 USER_NS_WRITE,
309 USER_NS_READ,
310 USER_NS_EXEC,
311 USER_TABLE_CREATE,
312 USER_TABLE_WRITE);
313 }
314
315 @Test
316 public void testGetNamespaceDescriptor() throws Exception {
317 AccessTestAction getNamespaceAction = new AccessTestAction() {
318 @Override
319 public Object run() throws Exception {
320 ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContext.createAndPrepare(CP_ENV, null),
321 TEST_NAMESPACE);
322 return null;
323 }
324 };
325
326 verifyAllowed(getNamespaceAction,
327 SUPERUSER,
328 USER_GLOBAL_ADMIN,
329 USER_NS_ADMIN);
330
331 verifyDenied(getNamespaceAction,
332 USER_GLOBAL_CREATE,
333 USER_GLOBAL_WRITE,
334 USER_GLOBAL_READ,
335 USER_GLOBAL_EXEC,
336 USER_NS_CREATE,
337 USER_NS_WRITE,
338 USER_NS_READ,
339 USER_NS_EXEC,
340 USER_TABLE_CREATE,
341 USER_TABLE_WRITE);
342 }
343
344 @Test
345 public void testListNamespaces() throws Exception {
346 AccessTestAction listAction = new AccessTestAction() {
347 @Override
348 public Object run() throws Exception {
349 HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
350 try {
351 return Arrays.asList(admin.listNamespaceDescriptors());
352 } finally {
353 admin.close();
354 }
355 }
356 };
357
358
359
360
361 verifyAllowed(listAction,
362 SUPERUSER,
363 USER_GLOBAL_ADMIN,
364 USER_NS_ADMIN);
365
366
367 assertEquals(4, ((List)SUPERUSER.runAs(listAction)).size());
368 assertEquals(4, ((List)USER_GLOBAL_ADMIN.runAs(listAction)).size());
369
370 assertEquals(2, ((List)USER_NS_ADMIN.runAs(listAction)).size());
371
372 assertEquals(0, ((List)USER_GLOBAL_CREATE.runAs(listAction)).size());
373 assertEquals(0, ((List)USER_GLOBAL_WRITE.runAs(listAction)).size());
374 assertEquals(0, ((List)USER_GLOBAL_READ.runAs(listAction)).size());
375 assertEquals(0, ((List)USER_GLOBAL_EXEC.runAs(listAction)).size());
376 assertEquals(0, ((List)USER_NS_CREATE.runAs(listAction)).size());
377 assertEquals(0, ((List)USER_NS_WRITE.runAs(listAction)).size());
378 assertEquals(0, ((List)USER_NS_READ.runAs(listAction)).size());
379 assertEquals(0, ((List)USER_NS_EXEC.runAs(listAction)).size());
380 assertEquals(0, ((List)USER_TABLE_CREATE.runAs(listAction)).size());
381 assertEquals(0, ((List)USER_TABLE_WRITE.runAs(listAction)).size());
382 }
383
384 @Test
385 public void testGrantRevoke() throws Exception{
386 final String testUser = "testUser";
387
388
389
390 AccessTestAction grantAction = new AccessTestAction() {
391 @Override
392 public Object run() throws Exception {
393 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
394 try {
395 BlockingRpcChannel service =
396 acl.coprocessorService(HConstants.EMPTY_START_ROW);
397 AccessControlService.BlockingInterface protocol =
398 AccessControlService.newBlockingStub(service);
399 ProtobufUtil.grant(protocol, testUser, TEST_NAMESPACE, Action.WRITE);
400 } finally {
401 acl.close();
402 }
403 return null;
404 }
405 };
406
407 AccessTestAction grantNamespaceAction = new AccessTestAction() {
408 @Override
409 public Object run() throws Exception {
410 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
411 try {
412 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
413 AccessControlService.BlockingInterface protocol =
414 AccessControlService.newBlockingStub(service);
415 ProtobufUtil.grant(protocol, USER_GROUP_NS_ADMIN.getShortName(),
416 TEST_NAMESPACE, Action.READ);
417 } finally {
418 acl.close();
419 }
420 return null;
421 }
422 };
423
424 AccessTestAction revokeAction = new AccessTestAction() {
425 public Object run() throws Exception {
426 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
427 try {
428 BlockingRpcChannel service =
429 acl.coprocessorService(HConstants.EMPTY_START_ROW);
430 AccessControlService.BlockingInterface protocol =
431 AccessControlService.newBlockingStub(service);
432 ProtobufUtil.revoke(protocol, testUser, TEST_NAMESPACE, Action.WRITE);
433 } finally {
434 acl.close();
435 }
436 return null;
437 }
438 };
439
440 AccessTestAction revokeNamespaceAction = new AccessTestAction() {
441 public Object run() throws Exception {
442 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
443 try {
444 BlockingRpcChannel service =
445 acl.coprocessorService(HConstants.EMPTY_START_ROW);
446 AccessControlService.BlockingInterface protocol =
447 AccessControlService.newBlockingStub(service);
448 ProtobufUtil.revoke(protocol, USER_GROUP_NS_ADMIN.getShortName(),
449 TEST_NAMESPACE, Action.READ);
450 } finally {
451 acl.close();
452 }
453 return null;
454 }
455 };
456
457 AccessTestAction getPermissionsAction = new AccessTestAction() {
458 @Override
459 public Object run() throws Exception {
460 HTable acl = new HTable(conf, AccessControlLists.ACL_TABLE_NAME);
461 try {
462 BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
463 AccessControlService.BlockingInterface protocol =
464 AccessControlService.newBlockingStub(service);
465 ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(TEST_NAMESPACE));
466 } finally {
467 acl.close();
468 }
469 return null;
470 }
471 };
472
473 verifyAllowed(grantAction,
474 SUPERUSER,
475 USER_GLOBAL_ADMIN,
476 USER_GROUP_ADMIN,
477 USER_NS_ADMIN);
478 verifyDenied(grantAction,
479 USER_GLOBAL_CREATE,
480 USER_GLOBAL_WRITE,
481 USER_GLOBAL_READ,
482 USER_GLOBAL_EXEC,
483 USER_NS_CREATE,
484 USER_NS_WRITE,
485 USER_NS_READ,
486 USER_NS_EXEC,
487 USER_TABLE_CREATE,
488 USER_TABLE_WRITE,
489 USER_GROUP_READ,
490 USER_GROUP_WRITE,
491 USER_GROUP_CREATE);
492
493 verifyAllowed(grantNamespaceAction,
494 SUPERUSER,
495 USER_GLOBAL_ADMIN,
496 USER_GROUP_ADMIN,
497 USER_NS_ADMIN,
498 USER_GROUP_NS_ADMIN);
499 verifyDenied(grantNamespaceAction,
500 USER_GLOBAL_CREATE,
501 USER_GLOBAL_WRITE,
502 USER_GLOBAL_READ,
503 USER_GLOBAL_EXEC,
504 USER_NS_CREATE,
505 USER_NS_WRITE,
506 USER_NS_READ,
507 USER_NS_EXEC,
508 USER_TABLE_CREATE,
509 USER_TABLE_WRITE,
510 USER_GROUP_READ,
511 USER_GROUP_WRITE,
512 USER_GROUP_CREATE);
513
514 verifyAllowed(revokeAction,
515 SUPERUSER,
516 USER_GLOBAL_ADMIN,
517 USER_GROUP_ADMIN,
518 USER_NS_ADMIN);
519 verifyDenied(revokeAction,
520 USER_GLOBAL_CREATE,
521 USER_GLOBAL_WRITE,
522 USER_GLOBAL_READ,
523 USER_GLOBAL_EXEC,
524 USER_NS_CREATE,
525 USER_NS_WRITE,
526 USER_NS_READ,
527 USER_NS_EXEC,
528 USER_TABLE_CREATE,
529 USER_TABLE_WRITE,
530 USER_GROUP_READ,
531 USER_GROUP_WRITE,
532 USER_GROUP_CREATE);
533
534 verifyAllowed(revokeNamespaceAction,
535 SUPERUSER,
536 USER_GLOBAL_ADMIN,
537 USER_GROUP_ADMIN,
538 USER_NS_ADMIN,
539 USER_GROUP_NS_ADMIN);
540 verifyDenied(revokeNamespaceAction,
541 USER_GLOBAL_CREATE,
542 USER_GLOBAL_WRITE,
543 USER_GLOBAL_READ,
544 USER_GLOBAL_EXEC,
545 USER_NS_CREATE,
546 USER_NS_WRITE,
547 USER_NS_READ,
548 USER_NS_EXEC,
549 USER_TABLE_CREATE,
550 USER_TABLE_WRITE,
551 USER_GROUP_READ,
552 USER_GROUP_WRITE,
553 USER_GROUP_CREATE);
554
555 verifyAllowed(getPermissionsAction,
556 SUPERUSER,
557 USER_GLOBAL_ADMIN,
558 USER_NS_ADMIN,
559 USER_GROUP_ADMIN);
560 verifyDenied(getPermissionsAction,
561 USER_GLOBAL_CREATE,
562 USER_GLOBAL_WRITE,
563 USER_GLOBAL_READ,
564 USER_GLOBAL_EXEC,
565 USER_NS_CREATE,
566 USER_NS_WRITE,
567 USER_NS_READ,
568 USER_NS_EXEC,
569 USER_TABLE_CREATE,
570 USER_TABLE_WRITE,
571 USER_GROUP_READ,
572 USER_GROUP_WRITE,
573 USER_GROUP_CREATE);
574 }
575
576 @Test
577 public void testCreateTableWithNamespace() throws Exception {
578 AccessTestAction createTable = new AccessTestAction() {
579 @Override
580 public Object run() throws Exception {
581 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TEST_TABLE));
582 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
583 ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null);
584 return null;
585 }
586 };
587
588
589 verifyAllowed(createTable,
590 SUPERUSER,
591 USER_GLOBAL_CREATE,
592 USER_NS_CREATE);
593
594 verifyDenied(createTable,
595 USER_GLOBAL_ADMIN,
596 USER_GLOBAL_WRITE,
597 USER_GLOBAL_READ,
598 USER_GLOBAL_EXEC,
599 USER_NS_ADMIN,
600 USER_NS_WRITE,
601 USER_NS_READ,
602 USER_NS_EXEC,
603 USER_TABLE_CREATE,
604 USER_TABLE_WRITE);
605 }
606 }