xref: /plan9/sys/src/cmd/cifs/transnt.c (revision 671dfc474d1a5bcbeda8be1356d2abfa05b91489)
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4 #include <thread.h>
5 #include <9p.h>
6 #include "cifs.h"
7 
8 static Pkt *
tnthdr(Session * s,Share * sp,int cmd)9 tnthdr(Session *s, Share *sp, int cmd)
10 {
11 	Pkt *p;
12 
13 	p = cifshdr(s, sp, SMB_COM_NT_TRANSACT);
14 	p->tbase = p8(p, 0);		/*  0  Max setup count to return */
15 	pl16(p, 0);			/*  1  reserved */
16 	pl32(p, 0);			/*  3  Total parameter count */
17 	pl32(p, 0);			/*  7  Total data count */
18 	pl32(p, 64);			/* 11  Max parameter count to return */
19 	pl32(p, (MTU - T2HDRLEN)-64);	/* 15  Max data count to return */
20 	pl32(p, 0);			/* 19  Parameter count (in this buffer) */
21 	pl32(p, 0);			/* 23  Offset to parameters (in this buffer) */
22 	pl32(p, 0);			/* 27  Count of data  in this buffer */
23 	pl32(p, 0);			/* 31  Offset to data in this buffer */
24 	p8(p, 1);			/* 35  Count of setup words */
25 	pl16(p, cmd);			/* 37  setup[0] */
26 	pl16(p, 0);			/* padding ??!?!? */
27 	pbytes(p);
28 	return p;
29 }
30 
31 static void
ptntparam(Pkt * p)32 ptntparam(Pkt *p)
33 {
34 	uchar *pos = p->pos;
35 	assert(p->tbase != 0);
36 
37 	p->pos = p->tbase +23;
38 	pl32(p, (pos - p->buf) - NBHDRLEN); /* param offset */
39 
40 	p->tparam = p->pos = pos;
41 }
42 
43 static void
ptntdata(Pkt * p)44 ptntdata(Pkt *p)
45 {
46 	uchar *pos = p->pos;
47 	assert(p->tbase != 0);
48 	assert(p->tparam != 0);
49 
50 	p->pos = p->tbase +3;
51 	pl32(p, pos - p->tparam);		/* total param count */
52 
53 	p->pos = p->tbase +19;
54 	pl32(p, pos - p->tparam);		/* param count */
55 
56 	p->pos = p->tbase +31;
57 	pl32(p, (pos - p->buf) - NBHDRLEN);	/* data offset */
58 	p->tdata = p->pos = pos;
59 }
60 
61 static int
tntrpc(Pkt * p)62 tntrpc(Pkt *p)
63 {
64 	int got;
65 	uchar *pos;
66 	assert(p->tbase != 0);
67 	assert(p->tdata != 0);
68 
69 	pos = p->pos;
70 
71 	p->pos = p->tbase +7;
72 	pl32(p, pos - p->tdata);		/* total data count */
73 
74 	p->pos = p->tbase +27;
75 	pl32(p, pos - p->tdata);		/* data count */
76 
77 	p->pos = pos;
78 	if((got = cifsrpc(p)) == -1)
79 		return -1;
80 
81 	g8(p);				/* Reserved */
82 	g8(p);				/* Reserved */
83 	g8(p);				/* Reserved */
84 	gl32(p);			/* Total parameter count */
85 	gl32(p);			/* Total data count */
86 	gl32(p);			/* Parameter count in this buffer */
87 	p->tparam = p->buf +NBHDRLEN +gl32(p); /* Parameter offset */
88 	gl32(p);			/* Parameter displacement */
89 	gl32(p);			/* Data count (this buffer); */
90 	p->tdata = p->buf +NBHDRLEN +gl32(p); /* Data offset */
91 	gl32(p);			/* Data displacement */
92 	g8(p);				/* Setup count */
93  	gl16(p);			/* padding ???  */
94 
95 	return got;
96 }
97 
98 static void
gtntparam(Pkt * p)99 gtntparam(Pkt *p)
100 {
101 	p->pos = p->tparam;
102 }
103 
104 static void
gtntdata(Pkt * p)105 gtntdata(Pkt *p)
106 {
107 	p->pos = p->tdata;
108 }
109 
110 
111 int
TNTquerysecurity(Session * s,Share * sp,int fh,char ** usid,char ** gsid)112 TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid)
113 {
114 	Pkt *p;
115 	uchar *base;
116 	Fmt fmt, *f = &fmt;
117 	int n, i, off2owner, off2group;
118 
119 	p = tnthdr(s, sp, NT_TRANSACT_QUERY_SECURITY_DESC);
120 	ptntparam(p);
121 
122 	pl16(p, fh); 		/* File handle */
123 	pl16(p, 0); 		/* Reserved */
124 	pl32(p, QUERY_OWNER_SECURITY_INFORMATION |
125 		QUERY_GROUP_SECURITY_INFORMATION);
126 
127 	ptntdata(p);
128 
129 	if(tntrpc(p) == -1){
130 		free(p);
131 		return -1;
132 	}
133 
134 	gtntdata(p);
135 
136 	base = p->pos;
137 	gl16(p);			/* revision */
138 	gl16(p);			/* type */
139 	off2owner = gl32(p);		/* offset to owner */
140 	off2group = gl32(p);		/* offset to group */
141 	gl32(p);
142 	gl32(p);
143 
144 	if(off2owner){
145 		p->pos = base +  off2owner;
146 		fmtstrinit(f);
147 		fmtprint(f, "S-%ud", g8(p));	/* revision */
148 		n = g8(p);			/* num auth */
149 		fmtprint(f, "-%llud", gb48(p));	/* authority */
150 		for(i = 0; i < n; i++)
151 			fmtprint(f, "-%ud", gl32(p));	/* sub-authorities */
152 		*usid = fmtstrflush(f);
153 	}
154 
155 	if(off2group){
156 		p->pos = base +  off2group;
157 		fmtstrinit(f);
158 		fmtprint(f, "S-%ud", g8(p));	/* revision */
159 		n = g8(p);			/* num auth */
160 		fmtprint(f, "-%llud", gb48(p));	/* authority */
161 		for(i = 0; i < n; i++)
162 			fmtprint(f, "-%ud", gl32(p));	/* sub-authorities */
163 		*gsid = fmtstrflush(f);
164 	}
165 	free(p);
166 	return 0;
167 }
168