Merge lp:~ssalley/ubuntu/natty/likewise-open/likewise-open-fix-724038 into lp:ubuntu/natty/likewise-open

Proposed by Scott Salley
Status: Rejected
Rejected by: Martin Pitt
Proposed branch: lp:~ssalley/ubuntu/natty/likewise-open/likewise-open-fix-724038
Merge into: lp:ubuntu/natty/likewise-open
Diff against target: 4806 lines (+4681/-3)
20 files modified
debian/changelog (+8/-0)
debian/likewise-open.install (+5/-0)
debian/rules (+3/-3)
git-build/build/components/lwconfig.comp (+82/-0)
lwconfig/COPYING-GPL (+339/-0)
lwconfig/Makefile.am (+3/-0)
lwconfig/autogen.sh (+2/-0)
lwconfig/configure.ac (+187/-0)
lwconfig/etc/Makefile.am (+1/-0)
lwconfig/etc/lwconfig.xml.in (+721/-0)
lwconfig/include/keep-me (+1/-0)
lwconfig/src/Makefile.am (+19/-0)
lwconfig/src/capability.c (+1788/-0)
lwconfig/src/capability.h (+72/-0)
lwconfig/src/defs.h (+49/-0)
lwconfig/src/includes.h (+53/-0)
lwconfig/src/main.c (+545/-0)
lwconfig/src/structs.h (+48/-0)
lwconfig/src/util.c (+660/-0)
lwconfig/src/util.h (+95/-0)
To merge this branch: bzr merge lp:~ssalley/ubuntu/natty/likewise-open/likewise-open-fix-724038
Reviewer Review Type Date Requested Status
Marc Deslauriers Needs Fixing
Ubuntu branches Pending
Review via email: mp+51067@code.launchpad.net

Description of the change

This merges the tool lwconfig from upstream. We originally forgot to export lwconfig from our internal subversion repository to the external git mirror. lwconfig consists of a binary (/usr/bin/lwconfig) and a recipe file (/var/lib/likewise-open/lwconfig.xml).

Impact:
This tool makes configuring likewise-open easier for users by encapsulating a series of actions in a single command and is frequently leveraged by the documentation.

This tool does not interact with the authentication system and will not open security holes.

To post a comment you must log in.
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

You need to add the missing files as a patch in debian/patches, and not inline, since there is a patch system in the packaging.

Please make the necessary corrections and re-propose for merging. Thanks!

review: Needs Fixing
Revision history for this message
Scott Salley (ssalley) wrote :

I wasn't sure how to update this merge with a completely new revision or even if that was important, so I started a new marge request here:

https://code.launchpad.net/~ssalley/ubuntu/natty/likewise-open/likewise-open-fix-724038-2/+merge/51201

Revision history for this message
Martin Pitt (pitti) wrote :

Scott,

you can just commit fixes and then followup here with setting it back to "Resubmit", the diff will update automatically. Anyway, closing this one, as we have a new MP now.

Unmerged revisions

22. By Scott Salley

* added lwconfig/ from upstream that was mistakenly left out. (LP: #724038)
  - added lwconfig/ and build/components/lwconfig.comp from upstream
  - updated debian/rules, debian/likewise-open.install for lwconfig

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2011-02-10 11:15:29 +0000
3+++ debian/changelog 2011-02-24 04:27:55 +0000
4@@ -1,3 +1,11 @@
5+likewise-open (6.0.0.53010-4) natty; urgency=low
6+
7+ * added lwconfig/ from upstream that was mistakenly left out. (LP: #724038)
8+ - added lwconfig/ and build/components/lwconfig.comp from upstream
9+ - updated debian/rules, debian/likewise-open.install for lwconfig
10+
11+ -- Scott Salley <ssalley@likewise.com> Thu, 23 Feb 2011 16:25:22 -0800
12+
13 likewise-open (6.0.0.53010-3) natty; urgency=low
14
15 * LP: #716615
16
17=== modified file 'debian/likewise-open.install'
18--- debian/likewise-open.install 2010-11-22 12:06:00 +0000
19+++ debian/likewise-open.install 2011-02-24 04:27:55 +0000
20@@ -185,3 +185,8 @@
21
22 # apparmor HOMEDIRS tunable
23 etc/apparmor.d/tunables/home.d/likewise-open
24+
25+# lwconfig
26+usr/bin/lwconfig
27+var/lib/likewise-open/lwconfig.xml
28+
29
30=== modified file 'debian/rules'
31--- debian/rules 2011-01-24 15:57:30 +0000
32+++ debian/rules 2011-02-24 04:27:55 +0000
33@@ -48,8 +48,8 @@
34 for f in lwbase lwmsg \
35 lwreg pstore lwadvapi centutils netlogon lwio lwsm libschannel \
36 dcerpc eventlog lsass lwdns \
37- domainjoin srvsvc lwnetapi lwtools lwupgrade; do \
38- echo $$f && (cd $$f && ./autogen.sh) || exit 1;\
39+ domainjoin srvsvc lwnetapi lwtools lwconfig lwupgrade; do \
40+ echo $$f && (cd $$f && chmod +x ./autogen.sh && ./autogen.sh) || exit 1;\
41 done
42 find . -type d -name autom4te.cache | xargs /bin/rm -rf
43 touch configure-stamp
44@@ -62,7 +62,7 @@
45 for comp in lwbase lwmsg \
46 lwreg pstore lwadvapi centutils netlogon lwio lwsm libschannel \
47 dcerpc eventlog lsass lwdns \
48- domainjoin srvsvc lwnetapi lwtools lwupgrade; do \
49+ domainjoin srvsvc lwnetapi lwtools lwconfig lwupgrade; do \
50 env BUILD_LOCALSTATEDIR=$(LOCALSTATEDIR) \
51 BUILD_SYSCONFDIR=$(SYSCONFDIR) \
52 BUILD_LIBDIR="lib/$(PKGNAME)" \
53
54=== added file 'git-build/build/components/lwconfig.comp'
55--- git-build/build/components/lwconfig.comp 1970-01-01 00:00:00 +0000
56+++ git-build/build/components/lwconfig.comp 2011-02-24 04:27:55 +0000
57@@ -0,0 +1,82 @@
58+#!/bin/sh
59+
60+COMP_NAME="lwconfig"
61+COMP_SOURCES="${BUILD_ROOT}/${COMP_NAME}"
62+
63+
64+function _setup_build_env
65+{
66+ set_compiler_env
67+
68+ cd ${COMP_SOURCES}/.
69+ exit_on_error $?
70+
71+ CPPFLAGS="${_cppflags} -I/usr/include/libxml2"
72+ CFLAGS="${_cflags}"
73+ LDFLAGS="${_ldflags}"
74+
75+ export PATH CPPFLAGS LDFLAGS CFLAGS CC
76+}
77+
78+function component_configure
79+{
80+ _setup_build_env
81+
82+ run_autogen ${COMP_SOURCES}
83+ exit_on_error $?
84+
85+ ./configure \
86+ --prefix=${PREFIXDIR} \
87+ --libdir=${PREFIXDIR}/${_lib} \
88+ --localstatedir=${LOCALSTATEDIR} \
89+ --sysconfdir=${SYSCONFDIR}
90+ exit_on_error $?
91+}
92+
93+function component_build
94+{
95+ _setup_build_env
96+
97+ ${MAKE} ${_mflags} all
98+}
99+
100+function component_install
101+{
102+ _setup_build_env
103+
104+ local INSTALL_ROOT="${STAGE_COMP_DIR}/${COMP_NAME}"
105+
106+ [ "$INSTALL_ROOT" != "/" ] && rm -rf $INSTALL_ROOT
107+ mkdir -p ${INSTALL_ROOT}
108+ mkdir -p ${STAGE_INSTALL_DIR}
109+
110+ ${MAKE} DESTDIR=${INSTALL_ROOT} install
111+
112+ rsync -a ${INSTALL_ROOT}/ ${STAGE_INSTALL_DIR}/
113+
114+ libtool_rewrite_staging
115+}
116+
117+function component_populate
118+{
119+ local INSTALL_ROOT="${STAGE_COMP_DIR}/${COMP_NAME}"
120+ local INSTALL_PREFIX_DIR="${INSTALL_ROOT}/${PREFIXDIR}"
121+ local STAGING_PREFIX_DIR="${STAGE_INSTALL_DIR}/${PREFIXDIR}"
122+ local STAGING_SYSCONF_DIR="${STAGE_INSTALL_DIR}/${SYSCONFDIR}"
123+
124+ local POPULATE_DIR="$1"
125+ local EXCLUDE_FILE="${POPULATE_DIR}/../exclude.files"
126+
127+ if [ -z "${POPULATE_DIR}" ] || [ ! -d "${POPULATE_DIR}" ]; then
128+ echo "Non-existent or invalid populate dircetory given: ${POPULATE_DIR}"
129+ return 1
130+ fi
131+
132+ cat <<EOF > ${EXCLUDE_FILE}
133+share
134+*.a
135+*.la
136+EOF
137+
138+ rsync -a --exclude-from=${EXCLUDE_FILE} ${INSTALL_ROOT}/ ${POPULATE_DIR}/
139+}
140
141=== added directory 'lwconfig'
142=== added file 'lwconfig/COPYING-GPL'
143--- lwconfig/COPYING-GPL 1970-01-01 00:00:00 +0000
144+++ lwconfig/COPYING-GPL 2011-02-24 04:27:55 +0000
145@@ -0,0 +1,339 @@
146+ GNU GENERAL PUBLIC LICENSE
147+ Version 2, June 1991
148+
149+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
150+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
151+ Everyone is permitted to copy and distribute verbatim copies
152+ of this license document, but changing it is not allowed.
153+
154+ Preamble
155+
156+ The licenses for most software are designed to take away your
157+freedom to share and change it. By contrast, the GNU General Public
158+License is intended to guarantee your freedom to share and change free
159+software--to make sure the software is free for all its users. This
160+General Public License applies to most of the Free Software
161+Foundation's software and to any other program whose authors commit to
162+using it. (Some other Free Software Foundation software is covered by
163+the GNU Lesser General Public License instead.) You can apply it to
164+your programs, too.
165+
166+ When we speak of free software, we are referring to freedom, not
167+price. Our General Public Licenses are designed to make sure that you
168+have the freedom to distribute copies of free software (and charge for
169+this service if you wish), that you receive source code or can get it
170+if you want it, that you can change the software or use pieces of it
171+in new free programs; and that you know you can do these things.
172+
173+ To protect your rights, we need to make restrictions that forbid
174+anyone to deny you these rights or to ask you to surrender the rights.
175+These restrictions translate to certain responsibilities for you if you
176+distribute copies of the software, or if you modify it.
177+
178+ For example, if you distribute copies of such a program, whether
179+gratis or for a fee, you must give the recipients all the rights that
180+you have. You must make sure that they, too, receive or can get the
181+source code. And you must show them these terms so they know their
182+rights.
183+
184+ We protect your rights with two steps: (1) copyright the software, and
185+(2) offer you this license which gives you legal permission to copy,
186+distribute and/or modify the software.
187+
188+ Also, for each author's protection and ours, we want to make certain
189+that everyone understands that there is no warranty for this free
190+software. If the software is modified by someone else and passed on, we
191+want its recipients to know that what they have is not the original, so
192+that any problems introduced by others will not reflect on the original
193+authors' reputations.
194+
195+ Finally, any free program is threatened constantly by software
196+patents. We wish to avoid the danger that redistributors of a free
197+program will individually obtain patent licenses, in effect making the
198+program proprietary. To prevent this, we have made it clear that any
199+patent must be licensed for everyone's free use or not licensed at all.
200+
201+ The precise terms and conditions for copying, distribution and
202+modification follow.
203+
204+ GNU GENERAL PUBLIC LICENSE
205+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
206+
207+ 0. This License applies to any program or other work which contains
208+a notice placed by the copyright holder saying it may be distributed
209+under the terms of this General Public License. The "Program", below,
210+refers to any such program or work, and a "work based on the Program"
211+means either the Program or any derivative work under copyright law:
212+that is to say, a work containing the Program or a portion of it,
213+either verbatim or with modifications and/or translated into another
214+language. (Hereinafter, translation is included without limitation in
215+the term "modification".) Each licensee is addressed as "you".
216+
217+Activities other than copying, distribution and modification are not
218+covered by this License; they are outside its scope. The act of
219+running the Program is not restricted, and the output from the Program
220+is covered only if its contents constitute a work based on the
221+Program (independent of having been made by running the Program).
222+Whether that is true depends on what the Program does.
223+
224+ 1. You may copy and distribute verbatim copies of the Program's
225+source code as you receive it, in any medium, provided that you
226+conspicuously and appropriately publish on each copy an appropriate
227+copyright notice and disclaimer of warranty; keep intact all the
228+notices that refer to this License and to the absence of any warranty;
229+and give any other recipients of the Program a copy of this License
230+along with the Program.
231+
232+You may charge a fee for the physical act of transferring a copy, and
233+you may at your option offer warranty protection in exchange for a fee.
234+
235+ 2. You may modify your copy or copies of the Program or any portion
236+of it, thus forming a work based on the Program, and copy and
237+distribute such modifications or work under the terms of Section 1
238+above, provided that you also meet all of these conditions:
239+
240+ a) You must cause the modified files to carry prominent notices
241+ stating that you changed the files and the date of any change.
242+
243+ b) You must cause any work that you distribute or publish, that in
244+ whole or in part contains or is derived from the Program or any
245+ part thereof, to be licensed as a whole at no charge to all third
246+ parties under the terms of this License.
247+
248+ c) If the modified program normally reads commands interactively
249+ when run, you must cause it, when started running for such
250+ interactive use in the most ordinary way, to print or display an
251+ announcement including an appropriate copyright notice and a
252+ notice that there is no warranty (or else, saying that you provide
253+ a warranty) and that users may redistribute the program under
254+ these conditions, and telling the user how to view a copy of this
255+ License. (Exception: if the Program itself is interactive but
256+ does not normally print such an announcement, your work based on
257+ the Program is not required to print an announcement.)
258+
259+These requirements apply to the modified work as a whole. If
260+identifiable sections of that work are not derived from the Program,
261+and can be reasonably considered independent and separate works in
262+themselves, then this License, and its terms, do not apply to those
263+sections when you distribute them as separate works. But when you
264+distribute the same sections as part of a whole which is a work based
265+on the Program, the distribution of the whole must be on the terms of
266+this License, whose permissions for other licensees extend to the
267+entire whole, and thus to each and every part regardless of who wrote it.
268+
269+Thus, it is not the intent of this section to claim rights or contest
270+your rights to work written entirely by you; rather, the intent is to
271+exercise the right to control the distribution of derivative or
272+collective works based on the Program.
273+
274+In addition, mere aggregation of another work not based on the Program
275+with the Program (or with a work based on the Program) on a volume of
276+a storage or distribution medium does not bring the other work under
277+the scope of this License.
278+
279+ 3. You may copy and distribute the Program (or a work based on it,
280+under Section 2) in object code or executable form under the terms of
281+Sections 1 and 2 above provided that you also do one of the following:
282+
283+ a) Accompany it with the complete corresponding machine-readable
284+ source code, which must be distributed under the terms of Sections
285+ 1 and 2 above on a medium customarily used for software interchange; or,
286+
287+ b) Accompany it with a written offer, valid for at least three
288+ years, to give any third party, for a charge no more than your
289+ cost of physically performing source distribution, a complete
290+ machine-readable copy of the corresponding source code, to be
291+ distributed under the terms of Sections 1 and 2 above on a medium
292+ customarily used for software interchange; or,
293+
294+ c) Accompany it with the information you received as to the offer
295+ to distribute corresponding source code. (This alternative is
296+ allowed only for noncommercial distribution and only if you
297+ received the program in object code or executable form with such
298+ an offer, in accord with Subsection b above.)
299+
300+The source code for a work means the preferred form of the work for
301+making modifications to it. For an executable work, complete source
302+code means all the source code for all modules it contains, plus any
303+associated interface definition files, plus the scripts used to
304+control compilation and installation of the executable. However, as a
305+special exception, the source code distributed need not include
306+anything that is normally distributed (in either source or binary
307+form) with the major components (compiler, kernel, and so on) of the
308+operating system on which the executable runs, unless that component
309+itself accompanies the executable.
310+
311+If distribution of executable or object code is made by offering
312+access to copy from a designated place, then offering equivalent
313+access to copy the source code from the same place counts as
314+distribution of the source code, even though third parties are not
315+compelled to copy the source along with the object code.
316+
317+ 4. You may not copy, modify, sublicense, or distribute the Program
318+except as expressly provided under this License. Any attempt
319+otherwise to copy, modify, sublicense or distribute the Program is
320+void, and will automatically terminate your rights under this License.
321+However, parties who have received copies, or rights, from you under
322+this License will not have their licenses terminated so long as such
323+parties remain in full compliance.
324+
325+ 5. You are not required to accept this License, since you have not
326+signed it. However, nothing else grants you permission to modify or
327+distribute the Program or its derivative works. These actions are
328+prohibited by law if you do not accept this License. Therefore, by
329+modifying or distributing the Program (or any work based on the
330+Program), you indicate your acceptance of this License to do so, and
331+all its terms and conditions for copying, distributing or modifying
332+the Program or works based on it.
333+
334+ 6. Each time you redistribute the Program (or any work based on the
335+Program), the recipient automatically receives a license from the
336+original licensor to copy, distribute or modify the Program subject to
337+these terms and conditions. You may not impose any further
338+restrictions on the recipients' exercise of the rights granted herein.
339+You are not responsible for enforcing compliance by third parties to
340+this License.
341+
342+ 7. If, as a consequence of a court judgment or allegation of patent
343+infringement or for any other reason (not limited to patent issues),
344+conditions are imposed on you (whether by court order, agreement or
345+otherwise) that contradict the conditions of this License, they do not
346+excuse you from the conditions of this License. If you cannot
347+distribute so as to satisfy simultaneously your obligations under this
348+License and any other pertinent obligations, then as a consequence you
349+may not distribute the Program at all. For example, if a patent
350+license would not permit royalty-free redistribution of the Program by
351+all those who receive copies directly or indirectly through you, then
352+the only way you could satisfy both it and this License would be to
353+refrain entirely from distribution of the Program.
354+
355+If any portion of this section is held invalid or unenforceable under
356+any particular circumstance, the balance of the section is intended to
357+apply and the section as a whole is intended to apply in other
358+circumstances.
359+
360+It is not the purpose of this section to induce you to infringe any
361+patents or other property right claims or to contest validity of any
362+such claims; this section has the sole purpose of protecting the
363+integrity of the free software distribution system, which is
364+implemented by public license practices. Many people have made
365+generous contributions to the wide range of software distributed
366+through that system in reliance on consistent application of that
367+system; it is up to the author/donor to decide if he or she is willing
368+to distribute software through any other system and a licensee cannot
369+impose that choice.
370+
371+This section is intended to make thoroughly clear what is believed to
372+be a consequence of the rest of this License.
373+
374+ 8. If the distribution and/or use of the Program is restricted in
375+certain countries either by patents or by copyrighted interfaces, the
376+original copyright holder who places the Program under this License
377+may add an explicit geographical distribution limitation excluding
378+those countries, so that distribution is permitted only in or among
379+countries not thus excluded. In such case, this License incorporates
380+the limitation as if written in the body of this License.
381+
382+ 9. The Free Software Foundation may publish revised and/or new versions
383+of the General Public License from time to time. Such new versions will
384+be similar in spirit to the present version, but may differ in detail to
385+address new problems or concerns.
386+
387+Each version is given a distinguishing version number. If the Program
388+specifies a version number of this License which applies to it and "any
389+later version", you have the option of following the terms and conditions
390+either of that version or of any later version published by the Free
391+Software Foundation. If the Program does not specify a version number of
392+this License, you may choose any version ever published by the Free Software
393+Foundation.
394+
395+ 10. If you wish to incorporate parts of the Program into other free
396+programs whose distribution conditions are different, write to the author
397+to ask for permission. For software which is copyrighted by the Free
398+Software Foundation, write to the Free Software Foundation; we sometimes
399+make exceptions for this. Our decision will be guided by the two goals
400+of preserving the free status of all derivatives of our free software and
401+of promoting the sharing and reuse of software generally.
402+
403+ NO WARRANTY
404+
405+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
406+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
407+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
408+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
409+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
410+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
411+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
412+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
413+REPAIR OR CORRECTION.
414+
415+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
416+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
417+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
418+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
419+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
420+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
421+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
422+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
423+POSSIBILITY OF SUCH DAMAGES.
424+
425+ END OF TERMS AND CONDITIONS
426+
427+ How to Apply These Terms to Your New Programs
428+
429+ If you develop a new program, and you want it to be of the greatest
430+possible use to the public, the best way to achieve this is to make it
431+free software which everyone can redistribute and change under these terms.
432+
433+ To do so, attach the following notices to the program. It is safest
434+to attach them to the start of each source file to most effectively
435+convey the exclusion of warranty; and each file should have at least
436+the "copyright" line and a pointer to where the full notice is found.
437+
438+ <one line to give the program's name and a brief idea of what it does.>
439+ Copyright (C) <year> <name of author>
440+
441+ This program is free software; you can redistribute it and/or modify
442+ it under the terms of the GNU General Public License as published by
443+ the Free Software Foundation; either version 2 of the License, or
444+ (at your option) any later version.
445+
446+ This program is distributed in the hope that it will be useful,
447+ but WITHOUT ANY WARRANTY; without even the implied warranty of
448+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
449+ GNU General Public License for more details.
450+
451+ You should have received a copy of the GNU General Public License along
452+ with this program; if not, write to the Free Software Foundation, Inc.,
453+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
454+
455+Also add information on how to contact you by electronic and paper mail.
456+
457+If the program is interactive, make it output a short notice like this
458+when it starts in an interactive mode:
459+
460+ Gnomovision version 69, Copyright (C) year name of author
461+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
462+ This is free software, and you are welcome to redistribute it
463+ under certain conditions; type `show c' for details.
464+
465+The hypothetical commands `show w' and `show c' should show the appropriate
466+parts of the General Public License. Of course, the commands you use may
467+be called something other than `show w' and `show c'; they could even be
468+mouse-clicks or menu items--whatever suits your program.
469+
470+You should also get your employer (if you work as a programmer) or your
471+school, if any, to sign a "copyright disclaimer" for the program, if
472+necessary. Here is a sample; alter the names:
473+
474+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
475+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
476+
477+ <signature of Ty Coon>, 1 April 1989
478+ Ty Coon, President of Vice
479+
480+This General Public License does not permit incorporating your program into
481+proprietary programs. If your program is a subroutine library, you may
482+consider it more useful to permit linking proprietary applications with the
483+library. If this is what you want to do, use the GNU Lesser General
484+Public License instead of this License.
485
486=== added file 'lwconfig/Makefile.am'
487--- lwconfig/Makefile.am 1970-01-01 00:00:00 +0000
488+++ lwconfig/Makefile.am 2011-02-24 04:27:55 +0000
489@@ -0,0 +1,3 @@
490+SUBDIRS = \
491+ etc \
492+ src
493
494=== added file 'lwconfig/autogen.sh'
495--- lwconfig/autogen.sh 1970-01-01 00:00:00 +0000
496+++ lwconfig/autogen.sh 2011-02-24 04:27:55 +0000
497@@ -0,0 +1,2 @@
498+#!/bin/sh
499+autoreconf -fi
500
501=== added file 'lwconfig/configure.ac'
502--- lwconfig/configure.ac 1970-01-01 00:00:00 +0000
503+++ lwconfig/configure.ac 2011-02-24 04:27:55 +0000
504@@ -0,0 +1,187 @@
505+AC_PREREQ(2.59)
506+AC_INIT(lwconfig, 5.4, support@likewise.com)
507+AC_CANONICAL_TARGET
508+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
509+AC_CONFIG_HEADERS([include/config.h])
510+AC_CONFIG_MACRO_DIR(m4])
511+
512+AM_CPPFLAGS=""
513+AM_CFLAGS=""
514+AM_LDFLAGS=""
515+
516+default_skeldirs="/etc/skel"
517+default_homedir_prefix="/home"
518+enable_nss_enum_default="false"
519+
520+case "$host_os:$host_cpu" in
521+ linux*:*)
522+ AC_DEFINE([__LWI_LINUX___], [], [Defined if OS is Linux])
523+ ;;
524+ solaris*:*)
525+ AC_DEFINE([__LWI_SOLARIS__], [], [Define if OS is Solaris])
526+ ;;
527+ darwin*:*)
528+ default_skeldirs="System/LibraryUser Template/Non_localized, /System/Library/User Template/English.lproj"
529+ default_homedir_prefix="/Users"
530+ enable_nss_enum_default="true"
531+ AC_DEFINE([__LWI_DARWIN__], [], [Define if OS is Darwin])
532+ ;;
533+ freebsd*:*)
534+ AC_DEFINE([__LWI_FREEBSD__], [], [Define if OS is FreeBSD])
535+ ;;
536+ hpux*:hppa*)
537+ AC_DEFINE([__LWI_HP_UX__], [], [Define if OS is HP-UX])
538+ AC_DEFINE([_XOPEN_SOURCE_EXTENDED], [1], [Define on HP-UX])
539+ ;;
540+ hpux*:ia64*)
541+ AC_DEFINE([__LWI_HP_UX__], [], [Define if OS is HP-UX])
542+ AC_DEFINE([_XOPEN_SOURCE_EXTENDED], [1], [Define on HP-UX])
543+ ;;
544+ aix*:*)
545+ AC_DEFINE([__LWI_AIX__], [], [Define if OS is AIX])
546+ AC_DEFINE([_LINUX_SOURCE_COMPAT], [], [Enable Linux source compatibility on AIX])
547+ ;;
548+esac
549+
550+AC_SUBST(default_skeldirs)
551+AC_SUBST(default_homedir_prefix)
552+AC_SUBST(enable_nss_enum_default)
553+
554+# debugging
555+
556+AC_ARG_ENABLE([debug],
557+ [AC_HELP_STRING([--enable-debug], [enable debugging (default: disabled)])],
558+ [
559+ if test x"$enableval" = x"yes"
560+ then
561+ AM_CFLAGS="$AM_CFLAGS -g -O0"
562+ AM_CPPFLAGS="$AM_CPPFLAGS -DDEBUG"
563+ fi
564+ ])
565+
566+AC_ARG_WITH([lwadvapi],
567+ [AC_HELP_STRING([--with-lwadvapi=<dir>], [use lwadvapi located in prefix <dir>])],
568+ [
569+ LWADVAPI_INCLUDES="-I$withval/include"
570+ LWADVAPI_LDFLAGS="-L$withval/lib"
571+ ])
572+AC_ARG_WITH([lwadvapi-includes],
573+ [AC_HELP_STRING([--with-lwadvapi-includes=<dir>], [use lwadvapi includes located in <dir>])],
574+ [
575+ LWADVAPI_INCLUDES="-I$withval"
576+ ])
577+AC_ARG_WITH([lwadvapi-libs],
578+ [AC_HELP_STRING([--with-lwadvapi-libs=<dir>], [use lwadvapi libs located in <dir>])],
579+ [
580+ LWADVAPI_LDFLAGS="-L$withval"
581+ ])
582+
583+LWADVAPI_LIBS="-llwadvapi"
584+LWADVAPI_NOTHR_LIBS="-llwadvapi_nothr"
585+
586+AC_SUBST(LWADVAPI_INCLUDES)
587+AC_SUBST(LWADVAPI_LDFLAGS)
588+AC_SUBST(LWADVAPI_LIBS)
589+AC_SUBST(LWADVAPI_NOTHR_LIBS)
590+
591+# lwbase
592+
593+AC_ARG_WITH([lwbase],
594+ [AC_HELP_STRING([--with-lwbase=<dir>], [use lwbase located in prefix <dir>])],
595+ [
596+ LWBASE_INCLUDES="-I$withval/include"
597+ LWBASE_LDFLAGS="-L$withval/lib"
598+ ])
599+
600+AC_ARG_WITH([lwbase-includes],
601+ [AC_HELP_STRING([--with-lwbase-includes=<dir>], [use lwbase includes located in <dir>])],
602+ [
603+ LWBASE_INCLUDES="-I$withval"
604+ ])
605+
606+AC_ARG_WITH([lwbase-libs],
607+ [AC_HELP_STRING([--with-lwbase-libs=<dir>], [use lwbase libs located in <dir>])],
608+ [
609+ LWBASE_LDFLAGS="-L$withval"
610+ ])
611+LWBASE_LIBS=-llwbase
612+
613+AC_SUBST(LWBASE_INCLUDES)
614+AC_SUBST(LWBASE_LDFLAGS)
615+AC_SUBST(LWBASE_LIBS)
616+
617+
618+# lwreg
619+
620+AC_ARG_WITH([lwreg],
621+ [AC_HELP_STRING([--with-lwreg=<dir>], [use lwreg located in prefix <dir>])],
622+ [
623+ LWREG_INCLUDES="-I$withval/include"
624+ LWREG_LDFLAGS="-L$withval/lib"
625+ ])
626+
627+AC_ARG_WITH([lwreg-includes],
628+ [AC_HELP_STRING([--with-lwreg-includes=<dir>], [use lwreg includes located in <dir>])],
629+ [
630+ LWREG_INCLUDES="-I$withval"
631+ ])
632+
633+AC_ARG_WITH([lwreg-libs],
634+ [AC_HELP_STRING([--with-lwreg-libs=<dir>], [use lwreg libs located in <dir>])],
635+ [
636+ LWREG_LDFLAGS="-L$withval"
637+ ])
638+
639+LWREG_LIBS=-lregclient
640+
641+AC_SUBST(LWREG_INCLUDES)
642+AC_SUBST(LWREG_LDFLAGS)
643+AC_SUBST(LWREG_LIBS)
644+
645+XML2_INCLUDES=""
646+XML2_LDFLAGS=""
647+XML2_LIBS="-lxml2"
648+AC_SUBST(XML2_INCLUDES)
649+AC_SUBST(XML2_LDFLAGS)
650+AC_SUBST(XML2_LIBS)
651+
652+if test x"$localstatedir" = x"/var"; then
653+ lwconfigdir="$localstatedir/lib/likewise"
654+else
655+ lwconfigdir="$localstatedir"
656+fi
657+AC_SUBST(lwconfigdir)
658+AC_DEFINE_UNQUOTED(LWCONFIG_XML, "${lwconfigdir}/lwconfig.xml", "Path to lwconfig.xml")
659+
660+# Checks for library functions
661+AC_FUNC_MALLOC
662+AC_CHECK_FUNCS([strndup strncasecmp strtoul strtoll __strtoll])
663+
664+# Checks for header files.
665+AC_CHECK_HEADERS([string.h strings.h sys/types.h sys/varargs.h])
666+
667+CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_GNU_SOURCE"
668+
669+AM_CPPFLAGS="$AM_CPPFLAGS -I${top_srcdir}/include"
670+AM_CFLAGS="$AM_CFLAGS -Wall -Werror -fno-strict-aliasing"
671+
672+AC_SUBST(AM_CPPFLAGS)
673+AC_SUBST(AM_CFLAGS)
674+AC_SUBST(AM_LDFLAGS)
675+
676+# Checks for programs.
677+AC_PROG_CC
678+AC_PROG_LIBTOOL
679+
680+# Checks for typedefs, structures, and compiler characteristics.
681+AC_C_BIGENDIAN
682+
683+# Checks for library functions.
684+AC_HEADER_STDC
685+
686+AC_CONFIG_FILES([Makefile
687+ etc/Makefile
688+ etc/lwconfig.xml
689+ src/Makefile])
690+
691+AC_OUTPUT
692
693=== added directory 'lwconfig/etc'
694=== added file 'lwconfig/etc/Makefile.am'
695--- lwconfig/etc/Makefile.am 1970-01-01 00:00:00 +0000
696+++ lwconfig/etc/Makefile.am 2011-02-24 04:27:55 +0000
697@@ -0,0 +1,1 @@
698+lwconfig_DATA = lwconfig.xml
699
700=== added file 'lwconfig/etc/lwconfig.xml.in'
701--- lwconfig/etc/lwconfig.xml.in 1970-01-01 00:00:00 +0000
702+++ lwconfig/etc/lwconfig.xml.in 2011-02-24 04:27:55 +0000
703@@ -0,0 +1,721 @@
704+<?xml version="1.0" encoding="utf-8"?> <capabilities>
705+<section section="Eventlog">
706+
707+ <capability>
708+ <name>AllowDeleteTo</name>
709+ <description>List of users that can delete entries from log</description>
710+ <registry
711+ type="string"
712+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\AllowDeleteTo"
713+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\AllowDeleteTo"
714+ >
715+
716+ <description>A list of user names, group names, or SIDS separated by commas.</description>
717+ <default><value></value></default>
718+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
719+ </registry>
720+ </capability>
721+
722+ <capability>
723+ <name>AllowReadTo</name>
724+ <description>Allowed users that can read entries from log</description>
725+ <registry type="string"
726+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\AllowReadTo"
727+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\AllowReadTo">
728+ <description>A list of user names, group names, or SIDS separated by commas.</description>
729+ <default>
730+ <value></value>
731+ </default>
732+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
733+ </registry>
734+ </capability>
735+
736+ <capability>
737+ <name>AllowWriteTo</name>
738+ <description>Allowed users that can delete entries from log</description>
739+ <registry type="string"
740+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\AllowWriteTo"
741+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\AllowWriteTo" >
742+ <description>A list of user names, group names, or SIDS separated by commas.</description>
743+ <default>
744+ <value></value>
745+ </default>
746+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
747+ </registry>
748+ </capability>
749+ <capability>
750+ <name>MaxDiskUsage</name>
751+ <description>Max size in bytes of eventlog database</description>
752+ <registry type="dword"
753+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\MaxDiskUsage"
754+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\MaxDiskUsage" >
755+ <description>Size in bytes</description>
756+ <default>
757+ <value>100MB</value>
758+ </default>
759+ <accept>
760+ <range min="100" max="2147483648" />
761+ </accept>
762+ <unit suffix="B" multiplier="1" />
763+ <unit suffix="KB" multiplier="1024" />
764+ <unit suffix="MB" multiplier="1048576" />
765+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
766+ </registry>
767+ </capability>
768+ <capability>
769+ <name>MaxEventLifespan</name>
770+ <description>Maximum number of days that events are saved in eventlog</description>
771+ <registry type="dword"
772+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\MaxEventLifespan"
773+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\MaxEventLifespan" >
774+ <description>days</description>
775+ <default>
776+ <value>90</value>
777+ </default>
778+ <accept>
779+ <range min="1" max="365" />
780+ </accept>
781+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
782+ </registry>
783+ </capability>
784+ <capability>
785+ <name>MaxNumEvents</name>
786+ <description>Maximum number of events to hold in eventlog database</description>
787+ <registry type="dword"
788+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Parameters\MaxNumEvents"
789+ gp-path="HKEY_THIS_MACHINE\Policy\Services\eventlog\Parameters\MaxNumEvents" >
790+ <description>number of events</description>
791+ <default>
792+ <value>100000</value>
793+ </default>
794+ <accept>
795+ <range min="100" max="2000000" />
796+ </accept>
797+ <apply command="/opt/likewise/bin/lwsm restart eventlog" />
798+ </registry>
799+ </capability>
800+ </section>
801+<section section="Lsass">
802+ <capability>
803+ <name>DomainSeparator</name>
804+ <description>Character used to designate the domain name separator</description>
805+ <registry type="string"
806+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\DomainSeparator"
807+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\DomainSeparator" >
808+ <description>A single character this is not alphanumeric or the SpaceReplacement character.</description>
809+ <default>
810+ <value>\</value>
811+ </default>
812+ <reject>
813+ <pattern>..+</pattern>
814+ <pattern>[a-zA-Z0-9]</pattern>
815+ </reject>
816+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
817+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
818+ </registry>
819+ </capability>
820+ <capability>
821+ <name>SpaceReplacement</name>
822+ <description>Character used to designate space characters in names of objects</description>
823+ <registry type="string"
824+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\SpaceReplacement"
825+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\SpaceReplacement" >
826+ <description>A single character used in place of spaces in names of objects</description>
827+ <default>
828+ <value>^</value>
829+ </default>
830+ <reject>
831+ <pattern>..+</pattern>
832+ <pattern>[a-zA-Z0-9]</pattern>
833+ </reject>
834+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
835+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
836+ </registry>
837+ </capability>
838+ <capability>
839+ <name>EnableEventlog</name>
840+ <description>Configure lsass to log events to the event log</description>
841+ <registry type="boolean"
842+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\EnableEventLog"
843+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\EnableEventLog" >
844+ <default>
845+ <value>false</value>
846+ </default>
847+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
848+ </registry>
849+ </capability>
850+ <capability>
851+ <name>LogInvalidPasswords</name>
852+ <description>Configure lsass to log events for failed authentication attempts due to invalid passwords</description>
853+ <registry type="boolean"
854+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\LogInvalidPasswords"
855+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\LogInvalidPasswords" >
856+ <default>
857+ <value>false</value>
858+ </default>
859+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
860+ </registry>
861+ </capability>
862+</section>
863+<section section="Lsass - PAM">
864+ <capability>
865+ <name>DisplayMotd</name>
866+ <description>Display message of the day</description>
867+ <registry type="boolean"
868+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\PAM\DisplayMotd"
869+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\PAM\DisplayMotd" >
870+ <default>
871+ <value>false</value>
872+ </default>
873+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
874+ </registry>
875+ </capability>
876+ <capability>
877+ <name>PAMLogLevel</name>
878+ <description>Configure PAM lsass logging detail level</description>
879+ <registry type="string"
880+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\PAM\LogLevel"
881+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\PAM\LogLevel" >
882+ <default>
883+ <value>error</value>
884+ </default>
885+ <accept>
886+ <value>disabled</value>
887+ <value>error</value>
888+ <value>warning</value>
889+ <value>info</value>
890+ <value>verbose</value>
891+ </accept>
892+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
893+ </registry>
894+ </capability>
895+ <capability>
896+ <name>UserNotAllowedError</name>
897+ <description>Message displayed at console logon failed attempt</description>
898+ <registry type="string"
899+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\PAM\UserNotAllowedError"
900+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\PAM\UserNotAllowedError" >
901+ <description>Not allowed error</description>
902+ <default>
903+ <value>Access Denied</value>
904+ </default>
905+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
906+ </registry>
907+ </capability>
908+</section>
909+<section section="Lsass - Active Directory provider">
910+ <capability>
911+ <name>AssumeDefaultDomain</name>
912+ <description>Apply domain name prefix to account name at logon</description>
913+ <registry type="boolean"
914+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\AssumeDefaultDomain"
915+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\AssumeDefaultDomain" >
916+ <default>
917+ <value>false</value>
918+ </default>
919+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
920+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
921+ </registry>
922+ </capability>
923+ <capability>
924+ <name>CreateHomeDir</name>
925+ <description>Whether home directories should be automatically created upon user logon</description>
926+ <registry type="boolean"
927+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\CreateHomeDir"
928+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\CreateHomeDir" >
929+ <default>
930+ <value>true</value>
931+ </default>
932+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
933+ </registry>
934+ </capability>
935+ <capability>
936+ <name>CreateK5Login</name>
937+ <description>Whether .k5login file is to be created upon user logon</description>
938+ <registry type="boolean"
939+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\CreateK5Login"
940+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\CreateK5Login" >
941+ <default>
942+ <value>true</value>
943+ </default>
944+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
945+ </registry>
946+ </capability>
947+ <capability>
948+ <name>SyncSystemTime</name>
949+ <description>Whether system time should be syncronized with AD domain controller</description>
950+ <registry type="boolean"
951+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\SyncSystemTime"
952+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\SyncSystemTime" >
953+ <default>
954+ <value>true</value>
955+ </default>
956+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
957+ </registry>
958+ </capability>
959+ <capability>
960+ <name>TrimUserMembership</name>
961+ <description>Whether to remove a cached group membership entry derived from PAC with information from LDAP showing the user disappearing from a group.</description>
962+ <registry type="boolean"
963+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\TrimUserMembership"
964+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\TrimUserMembership" >
965+ <default>
966+ <value>true</value>
967+ </default>
968+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
969+ </registry>
970+ </capability>
971+ <capability>
972+ <name>LdapSignAndSeal</name>
973+ <description>Whether all LDAP traffic should be sent both signed and sealed</description>
974+ <registry type="boolean"
975+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\LdapSignAndSeal"
976+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\LdapSignAndSeal" >
977+ <default>
978+ <value>false</value>
979+ </default>
980+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
981+ </registry>
982+ </capability>
983+ <capability>
984+ <name>LogADNetworkConnectionEvents</name>
985+ <description>Configure lsass to log events for offline query failures and transitions</description>
986+ <registry type="boolean"
987+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\LogNetworkConnectionEvents"
988+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\LogNetworkConnectionEvents" >
989+ <default>
990+ <value>true</value>
991+ </default>
992+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
993+ </registry>
994+ </capability>
995+ <capability>
996+ <name>NssEnumerationEnabled</name>
997+ <description>Whether to enumerate users or groups for NSS</description>
998+ <registry type="boolean"
999+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\NssEnumerationEnabled"
1000+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\NssEnumerationEnabled" >
1001+ <default>
1002+ <value>@enable_nss_enum_default@</value>
1003+ </default>
1004+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1005+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1006+ </registry>
1007+ </capability>
1008+ <capability>
1009+ <name>NssGroupMembersQueryCacheOnly</name>
1010+ <description>Whether to return only cached info for NSS group members</description>
1011+ <registry type="boolean"
1012+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\NssGroupMembersQueryCacheOnly"
1013+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\NssGroupMembersQueryCacheOnly" >
1014+ <default>
1015+ <value>true</value>
1016+ </default>
1017+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1018+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1019+ </registry>
1020+ </capability>
1021+ <capability>
1022+ <name>NssUserMembershipQueryCacheOnly</name>
1023+ <description>Whether to return only cached info for NSS user's groups</description>
1024+ <registry type="boolean"
1025+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\NssUserMembershipQueryCacheOnly"
1026+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\NssUserMembershipQueryCacheOnly" >
1027+ <default>
1028+ <value>false</value>
1029+ </default>
1030+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1031+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1032+ </registry>
1033+ </capability>
1034+ <capability>
1035+ <name>RefreshUserCredentials</name>
1036+ <description>Whether to refresh user credentials agaist AD domain controller</description>
1037+ <registry type="boolean"
1038+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\RefreshUserCredentials"
1039+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\RefreshUserCredentials" >
1040+ <default>
1041+ <value>true</value>
1042+ </default>
1043+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1044+ </registry>
1045+ </capability>
1046+ <capability>
1047+ <name>CacheEntryExpiry</name>
1048+ <description>Duration for when lsass object cache entries are marked stale</description>
1049+ <registry type="dword"
1050+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\CacheEntryExpiry"
1051+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\CacheEntryExpiry" >
1052+ <description>Duration in seconds (s), minutes (m), hours (h) or days (d)</description>
1053+ <default>
1054+ <value>4h</value>
1055+ </default>
1056+ <accept>
1057+ <range min="0" max="86400" />
1058+ </accept>
1059+ <unit suffix="s" multiplier="1" />
1060+ <unit suffix="m" multiplier="60" />
1061+ <unit suffix="h" multiplier="3600" />
1062+ <unit suffix="d" multiplier="86400" />
1063+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1064+ </registry>
1065+ </capability>
1066+ <capability>
1067+ <name>TrustEnumerationWait</name>
1068+ <description>If true, wait for trust enumeration to complete before completing initialization.</description>
1069+ <registry type="boolean"
1070+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\TrustEnumerationWait"
1071+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\TrustEnumerationWait" >
1072+ <default>
1073+ <value>false</value>
1074+ </default>
1075+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1076+ </registry>
1077+ </capability>
1078+ <capability>
1079+ <name>TrustEnumerationWaitSeconds</name>
1080+ <description>If TrustEnumerationWait is true, the amount of time to wait for trust enumeration to complete before continuing. Use 0 to wait forever. </description>
1081+ <registry type="dword"
1082+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\TrustEnumerationWaitSeconds"
1083+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\TrustEnumerationWaitSeconds" >
1084+ <description>Duration in seconds (s), minutes (m), hours (h) or days (d)</description>
1085+ <default>
1086+ <value>0s</value>
1087+ </default>
1088+ <accept>
1089+ <range min="0" max="86400" />
1090+ </accept>
1091+ <unit suffix="s" multiplier="1" />
1092+ <unit suffix="m" multiplier="60" />
1093+ <unit suffix="h" multiplier="3600" />
1094+ <unit suffix="d" multiplier="86400" />
1095+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1096+ </registry>
1097+ </capability>
1098+ <capability>
1099+ <name>DomainManagerCheckDomainOnlineInterval</name>
1100+ <description>How often the domain manager should check whether a domain is back online</description>
1101+ <registry type="dword"
1102+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerCheckDomainOnlineInterval"
1103+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerCheckDomainOnlineInterval" >
1104+ <description>Duration in seconds (s), minutes (m), hours (h) or days (d)</description>
1105+ <default>
1106+ <value>5m</value>
1107+ </default>
1108+ <accept>
1109+ <range min="60" max="86400" />
1110+ </accept>
1111+ <unit suffix="s" multiplier="1" />
1112+ <unit suffix="m" multiplier="60" />
1113+ <unit suffix="h" multiplier="3600" />
1114+ <unit suffix="d" multiplier="86400" />
1115+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1116+ </registry>
1117+ </capability>
1118+ <capability>
1119+ <name>DomainManagerUnknownDomainCacheTimeout</name>
1120+ <description>How long an unknown domain is cached as unknown in the domain manager</description>
1121+ <registry type="dword"
1122+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerUnknownDomainCacheTimeout"
1123+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerUnknownDomainCacheTimeout" >
1124+ <description>Duration in seconds (s), minutes (m), hours (h) or days (d)</description>
1125+ <default>
1126+ <value>1h</value>
1127+ </default>
1128+ <accept>
1129+ <range min="60" max="86400" />
1130+ </accept>
1131+ <unit suffix="s" multiplier="1" />
1132+ <unit suffix="m" multiplier="60" />
1133+ <unit suffix="h" multiplier="3600" />
1134+ <unit suffix="d" multiplier="86400" />
1135+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1136+ </registry>
1137+ </capability>
1138+ <capability>
1139+ <name>MachinePasswordLifespan</name>
1140+ <description>Machine password expiration lifespan in seconds.</description>
1141+ <registry type="dword"
1142+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\MachinePasswordLifespan"
1143+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\MachinePasswordLifespan" >
1144+ <description>Duration in seconds (s), minutes (m), hours (h) or days (d). Example: 1d</description>
1145+ <default>
1146+ <value>30d</value>
1147+ </default>
1148+ <accept>
1149+ <range min="3600" max="31536000" />
1150+ </accept>
1151+ <accept>
1152+ <range min="0" max="0" />
1153+ </accept>
1154+ <unit suffix="s" multiplier="1" />
1155+ <unit suffix="m" multiplier="60" />
1156+ <unit suffix="h" multiplier="3600" />
1157+ <unit suffix="d" multiplier="86400" />
1158+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1159+ </registry>
1160+ </capability>
1161+ <capability>
1162+ <name>MemoryCacheSizeCap</name>
1163+ <description>The maximum bytes to use for the in-memory cache. Old data will be purged if the total cache size exceeds this limit. A value of 0 indicates no limit.</description>
1164+ <registry type="dword"
1165+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\MemoryCacheSizeCap"
1166+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\MemoryCacheSizeCap" >
1167+ <description>Size in bytes</description>
1168+ <default>
1169+ <value>0</value>
1170+ </default>
1171+ <unit suffix="B" multiplier="1" />
1172+ <unit suffix="KB" multiplier="1024" />
1173+ <unit suffix="MB" multiplier="1048576" />
1174+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1175+ </registry>
1176+ </capability>
1177+ <capability>
1178+ <name>HomeDirPrefix</name>
1179+ <description>Prefix path for user's home directory. This value is used in place of the %H in the HomeDirTemplate setting. Value must be an absolute path.</description>
1180+ <registry type="string"
1181+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirPrefix"
1182+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirPrefix" >
1183+ <description>Absolute path to the home directory.</description>
1184+ <default>
1185+ <value>@default_homedir_prefix@</value>
1186+ </default>
1187+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1188+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1189+ </registry>
1190+ </capability>
1191+ <capability>
1192+ <name>HomeDirTemplate</name>
1193+ <description>Format string for user's home directory path. This value can contain substitution string markers for HomeDirPrefix (%H), Domain (%D), and User (%U).</description>
1194+ <registry type="string"
1195+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirTemplate"
1196+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirTemplate" >
1197+ <description>Absolute path to the home directory.</description>
1198+ <default>
1199+ <value>%H/local/%D/%U</value>
1200+ </default>
1201+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1202+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1203+ </registry>
1204+ </capability>
1205+ <capability>
1206+ <name>HomeDirUmask</name>
1207+ <description>Umask for home directories</description>
1208+ <registry type="string"
1209+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirUmask"
1210+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\HomeDirUmask" >
1211+ <description>String of octal digits for home directory umask</description>
1212+ <default>
1213+ <value>022</value>
1214+ </default>
1215+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1216+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1217+ </registry>
1218+ </capability>
1219+ <capability>
1220+ <name>LoginShellTemplate</name>
1221+ <description>Default login shell template</description>
1222+ <registry type="string"
1223+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\LoginShellTemplate"
1224+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\LoginShellTemplate" >
1225+ <description>Path to shell</description>
1226+ <default>
1227+ <value>/bin/sh</value>
1228+ </default>
1229+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1230+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1231+ </registry>
1232+ </capability>
1233+ <capability>
1234+ <name>SkeletonDirs</name>
1235+ <description>Skeleton home directory template directories</description>
1236+ <registry type="string"
1237+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\SkeletonDirs"
1238+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\SkeletonDirs" >
1239+ <description>Comma separated list of skeleton directories.</description>
1240+ <default>
1241+ <value>@default_skeldirs@</value>
1242+ </default>
1243+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1244+ </registry>
1245+ </capability>
1246+ <capability>
1247+ <name>UserDomainPrefix</name>
1248+ <description>Domain short name prefix to be used when AssumeDefaultDomain setting is enabled</description>
1249+ <Allowed>Domain short name of Active Directory domain that the user accounts reside. Blank will use the domain name which the computer is joined to.</Allowed>
1250+ <registry type="string"
1251+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\UserDomainPrefix"
1252+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\UserDomainPrefix" >
1253+ <description>Short name of Active Directory domain where the user accounts reside. Blank means use the domain name to which the computer is joined.</description>
1254+ <default>
1255+ <value></value>
1256+ </default>
1257+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1258+ <apply command="/opt/likewise/bin/lw-ad-cache --delete-all" />
1259+ </registry>
1260+ </capability>
1261+ <capability>
1262+ <name>DomainManagerIgnoreAllTrusts</name>
1263+ <description>When true, ignore all trusts during domain enumeration.</description>
1264+ <registry type="boolean"
1265+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerIgnoreAllTrusts"
1266+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerIgnoreAllTrusts" >
1267+ <default>
1268+ <value>false</value>
1269+ </default>
1270+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1271+ </registry>
1272+ </capability>
1273+ <capability>
1274+ <name>DomainManagerIncludeTrustsList</name>
1275+ <description>When DomainManagerIgnoreAllTrusts is true, these trusts are included</description>
1276+ <registry type="multistring"
1277+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerIncludeTrustsList"
1278+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerIncludeTrustsList" >
1279+ <description>A list of trusts.</description>
1280+ <default>
1281+ <value></value>
1282+ </default>
1283+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1284+ </registry>
1285+ </capability>
1286+ <capability>
1287+ <name>DomainManagerExcludeTrustsList</name>
1288+ <description>When DomainManagerIgnoreAllTrusts is false, these trusts are excluded.</description>
1289+ <registry type="multistring"
1290+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerExcludeTrustsList"
1291+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\DomainManagerExcludeTrustsList" >
1292+ <description>A list of trusts.</description>
1293+ <default>
1294+ <value></value>
1295+ </default>
1296+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1297+ </registry>
1298+ </capability>
1299+ <capability>
1300+ <name>RequireMembershipOf</name>
1301+ <description>Restrict logon access to computer to specific users or group members, or SIDs</description>
1302+ <registry type="multistring"
1303+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\ActiveDirectory\RequireMembershipOf"
1304+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\ActiveDirectory\RequireMembershipOf" >
1305+ <description>User names, group names, or SIDs.</description>
1306+ <default>
1307+ <value></value>
1308+ </default>
1309+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1310+ </registry>
1311+ </capability>
1312+</section>
1313+<section section="Lsass - Local provider">
1314+ <capability>
1315+ <name>Local_AcceptNTLMv1</name>
1316+ <description></description>
1317+ <registry type="boolean"
1318+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\Local\AcceptNTLMv1"
1319+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\Local\AcceptNTLMv1" >
1320+ <default>
1321+ <value>true</value>
1322+ </default>
1323+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1324+ </registry>
1325+ </capability>
1326+ <capability>
1327+ <name>Local_HomeDirTemplate</name>
1328+ <description>Format string for lsass local provider account user's home directory path. This value can contain substitution string markers for HomeDirPrefix (%H), Domain (%D), and User (%U).</description>
1329+ <registry type="string"
1330+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\Local\HomeDirTemplate"
1331+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\Local\HomeDirTemplate" >
1332+ <description>Absolute path to the home directory.</description>
1333+ <default>
1334+ <value>%H/local/%D/%U</value>
1335+ </default>
1336+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1337+ </registry>
1338+ </capability>
1339+ <capability>
1340+ <name>Local_HomeDirUmask</name>
1341+ <description>Umask for lsass local provider account home directories</description>
1342+ <registry type="string"
1343+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\Local\HomeDirUmask"
1344+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\Local\HomeDirUmask" >
1345+ <description>Absolute path to the home directory.</description>
1346+ <default>
1347+ <value>022</value>
1348+ </default>
1349+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1350+ </registry>
1351+ </capability>
1352+ <capability>
1353+ <name>Local_LoginShellTemplate</name>
1354+ <description>Default login shell template for lsass local provider accounts</description>
1355+ <registry type="string"
1356+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\Local\LoginShellTemplate"
1357+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\Local\LoginShellTemplate" >
1358+ <description>Absolute path to the home directory.</description>
1359+ <default>
1360+ <value>/bin/sh</value>
1361+ </default>
1362+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1363+ </registry>
1364+ </capability>
1365+ <capability>
1366+ <name>Local_SkeletonDirs</name>
1367+ <description>Skeleton home directory template directories for lsass local provider accounts</description>
1368+ <registry type="string"
1369+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Parameters\Providers\Local\SkeletonDirs"
1370+ gp-path="HKEY_THIS_MACHINE\Policy\Services\lsass\Parameters\Providers\Local\SkeletonDirs" >
1371+ <description>Absolute path to the home directory.</description>
1372+ <default>
1373+ <value>@default_skeldirs@</value>
1374+ </default>
1375+ <apply command="/opt/likewise/bin/lwsm refresh lsass" />
1376+ </registry>
1377+ </capability>
1378+ </section>
1379+ <section section="System Initialization">
1380+ <capability>
1381+ <name>LsassAutostart</name>
1382+ <description>Start lsassd when lwsmd starts.</description>
1383+ <registry type="boolean"
1384+ lp-path="HKEY_THIS_MACHINE\Services\lsass\Autostart" >
1385+ <default>
1386+ <value>true</value>
1387+ </default>
1388+ </registry>
1389+ </capability>
1390+ <capability>
1391+ <name>EventlogAutostart</name>
1392+ <description>Start eventlogd when lwsmd starts.</description>
1393+ <registry type="boolean"
1394+ lp-path="HKEY_THIS_MACHINE\Services\eventlog\Autostart" >
1395+ <default>
1396+ <value>true</value>
1397+ </default>
1398+ </registry>
1399+ </capability>
1400+ <capability>
1401+ <name>GpagentAutostart</name>
1402+ <description>Start gpagentd when lwsmd starts.</description>
1403+ <registry type="boolean"
1404+ lp-path="HKEY_THIS_MACHINE\Services\gpagent\Autostart" >
1405+ <default>
1406+ <value>true</value>
1407+ </default>
1408+ </registry>
1409+ </capability>
1410+ </section>
1411+</capabilities>
1412+
1413+<!--
1414+#Additional Likewise settings to be converted to Capabilities
1415+
1416+[HKEY_THIS_MACHINE\Services\lsass\Parameters\NTLM]
1417+"SendNTLMv2"=dword:00000000
1418+"Support128bit"=dword:00000001
1419+"Support56bit"=dword:00000001
1420+"SupportKeyExchange"=dword:00000001
1421+"SupportNTLM2SessionSecurity"=dword:00000001
1422+"SupportUnicode"=dword:00000001
1423+
1424+-->
1425
1426=== added directory 'lwconfig/include'
1427=== added file 'lwconfig/include/keep-me'
1428--- lwconfig/include/keep-me 1970-01-01 00:00:00 +0000
1429+++ lwconfig/include/keep-me 2011-02-24 04:27:55 +0000
1430@@ -0,0 +1,1 @@
1431+keep-this-file
1432
1433=== added directory 'lwconfig/src'
1434=== added file 'lwconfig/src/Makefile.am'
1435--- lwconfig/src/Makefile.am 1970-01-01 00:00:00 +0000
1436+++ lwconfig/src/Makefile.am 2011-02-24 04:27:55 +0000
1437@@ -0,0 +1,19 @@
1438+bin_PROGRAMS = lwconfig
1439+
1440+lwconfig_SOURCES = \
1441+ capability.c \
1442+ main.c \
1443+ util.c
1444+
1445+lwconfig_CPPFLAGS = \
1446+ $(AM_CPPFLAGS) \
1447+ -I$(top_srcdir)/include \
1448+ $(XML2_INCLUDES) \
1449+ $(LWBASE_INCLUDES)
1450+
1451+lwconfig_LDADD = \
1452+ $(XML2_LIBS) \
1453+ $(LWBASE_LIBS) \
1454+ $(LWADVAPI_LIBS) \
1455+ $(LWREG_LIBS) \
1456+ -lregclient -lregcommon -llwadvapi_nothr
1457
1458=== added file 'lwconfig/src/capability.c'
1459--- lwconfig/src/capability.c 1970-01-01 00:00:00 +0000
1460+++ lwconfig/src/capability.c 2011-02-24 04:27:55 +0000
1461@@ -0,0 +1,1788 @@
1462+/*
1463+ * Copyright (c) Likewise Software. All rights reserved.
1464+ *
1465+ * This program is free software; you can redistribute it and/or modify
1466+ * it under the terms of the GNU General Public License as published by
1467+ * the Free Software Foundation; either version 2 of the License, or (at
1468+ * your option) any later version.
1469+ *
1470+ * This program is distributed in the hope that it will be useful, but
1471+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1472+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1473+ * for more details. You should have received a copy of the GNU General
1474+ * Public License along with this program. If not, see
1475+ * <http://www.gnu.org/licenses/>.
1476+ *
1477+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
1478+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
1479+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
1480+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
1481+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
1482+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
1483+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
1484+ * license@likewise.com
1485+ */
1486+
1487+#include "includes.h"
1488+
1489+static
1490+xmlNodePtr
1491+FindNext(
1492+ xmlNodePtr pxChild,
1493+ PSTR pszChild
1494+ );
1495+
1496+static
1497+DWORD
1498+DefaultValue(
1499+ xmlDocPtr xmlDoc,
1500+ xmlNodePtr pxDefault,
1501+ PSTR *ppszValue
1502+ );
1503+
1504+static
1505+DWORD
1506+GetLocalPolicyValue(
1507+ PCAPABILITY pCapability,
1508+ PSTR *ppszaValue
1509+ );
1510+
1511+static
1512+DWORD
1513+RegistryAllocate(
1514+ xmlDocPtr xmlDoc,
1515+ xmlNodePtr pxRegistry,
1516+ PREGISTRY *ppRegistry)
1517+{
1518+ DWORD dwError = 0;
1519+ PREGISTRY pRegistry = NULL;
1520+ xmlChar *xszLocalPath = NULL;
1521+ PSTR pszLocalPath = NULL;
1522+ xmlChar *xszPolicyPath = NULL;
1523+ PSTR pszPolicyPath = NULL;
1524+ xmlChar *xszType = NULL;
1525+ PSTR pszType = NULL;
1526+ xmlChar *xszDescription = NULL;
1527+ PSTR pszDescription = NULL;
1528+ PSTR pszaDefault = NULL;
1529+ xmlNodePtr child = NULL;
1530+
1531+ xszLocalPath = xmlGetProp(pxRegistry, (const xmlChar*)"lp-path");
1532+ xszPolicyPath = xmlGetProp(pxRegistry, (const xmlChar*)"gp-path");
1533+ xszType = xmlGetProp(pxRegistry, (const xmlChar*)"type");
1534+
1535+ if (!xszLocalPath && !xszPolicyPath)
1536+ {
1537+ dwError = APP_ERROR_XML_MISSING_ATTRIBUTE;
1538+ BAIL_ON_ERROR(dwError);
1539+ }
1540+
1541+ if (!xszType)
1542+ {
1543+ dwError = APP_ERROR_XML_MISSING_ATTRIBUTE;
1544+ BAIL_ON_ERROR(dwError);
1545+ }
1546+
1547+ if (xszLocalPath)
1548+ {
1549+ dwError = LwAllocateString((PCSTR)xszLocalPath, &pszLocalPath);
1550+ BAIL_ON_ERROR(dwError);
1551+ }
1552+
1553+ if (xszPolicyPath)
1554+ {
1555+ dwError = LwAllocateString((PCSTR)xszPolicyPath, &pszPolicyPath);
1556+ BAIL_ON_ERROR(dwError);
1557+ }
1558+
1559+ dwError = LwAllocateString((PCSTR)xszType, &pszType);
1560+ BAIL_ON_ERROR(dwError);
1561+
1562+ for (child = pxRegistry->xmlChildrenNode; child; child = child->next)
1563+ {
1564+ if (child->type != XML_ELEMENT_NODE)
1565+ continue;
1566+ if (!xmlStrcmp(child->name, (const xmlChar*)"default"))
1567+ {
1568+ dwError = DefaultValue(xmlDoc, child, &pszaDefault);
1569+ BAIL_ON_ERROR(dwError);
1570+ }
1571+ else if (!xmlStrcmp(child->name, (const xmlChar*)"description"))
1572+ {
1573+ xszDescription = xmlNodeListGetString(xmlDoc,
1574+ child->xmlChildrenNode, TRUE);
1575+ if (xszDescription)
1576+ {
1577+ dwError = LwAllocateString((PCSTR)xszDescription, &pszDescription);
1578+ BAIL_ON_ERROR(dwError);
1579+ }
1580+ }
1581+ }
1582+
1583+ dwError = LwAllocateMemory(sizeof(*pRegistry), (PVOID*)&pRegistry);
1584+ BAIL_ON_ERROR(dwError);
1585+
1586+ pRegistry->pxRegistry = pxRegistry;
1587+ pRegistry->pszLocalPath = pszLocalPath;
1588+ pRegistry->pszPolicyPath = pszPolicyPath;
1589+ pRegistry->pszType = pszType;
1590+ pRegistry->pszDescription = pszDescription;
1591+ pRegistry->pszaDefault = pszaDefault;
1592+
1593+ *ppRegistry = pRegistry;
1594+
1595+cleanup:
1596+
1597+ xmlFree(xszLocalPath);
1598+ xmlFree(xszPolicyPath);
1599+ xmlFree(xszType);
1600+ xmlFree(xszDescription);
1601+ return dwError;
1602+
1603+error:
1604+ LW_SAFE_FREE_STRING(pszLocalPath);
1605+ LW_SAFE_FREE_STRING(pszPolicyPath);
1606+ LW_SAFE_FREE_STRING(pszType);
1607+ LW_SAFE_FREE_STRING(pszDescription);
1608+ LW_SAFE_FREE_MEMORY(pszaDefault);
1609+ LW_SAFE_FREE_MEMORY(pRegistry);
1610+ goto cleanup;
1611+}
1612+
1613+static
1614+void
1615+RegistryFree(
1616+ PREGISTRY pRegistry
1617+ )
1618+{
1619+ if (pRegistry)
1620+ {
1621+ LW_SAFE_FREE_STRING(pRegistry->pszLocalPath);
1622+ LW_SAFE_FREE_STRING(pRegistry->pszPolicyPath);
1623+ LW_SAFE_FREE_STRING(pRegistry->pszType);
1624+ LW_SAFE_FREE_STRING(pRegistry->pszDescription);
1625+ LW_SAFE_FREE_MEMORY(pRegistry->pszaDefault);
1626+
1627+ LW_SAFE_FREE_MEMORY(pRegistry);
1628+ }
1629+}
1630+
1631+
1632+DWORD
1633+CapabilityAllocate(
1634+ xmlDocPtr xmlDoc,
1635+ xmlNodePtr xmlNodeCapability,
1636+ PCAPABILITY *ppCapability
1637+ )
1638+{
1639+ DWORD dwError = 0;
1640+ xmlChar *xszName = NULL;
1641+ PSTR pszName = NULL;
1642+ xmlChar *xszDescription = NULL;
1643+ PSTR pszDescription = NULL;
1644+ xmlNodePtr child = NULL;
1645+ PREGISTRY pRegistry = NULL;
1646+ PCAPABILITY pCapability = NULL;
1647+
1648+ if (!xmlNodeCapability)
1649+ {
1650+ dwError = ERROR_INVALID_PARAMETER;
1651+ BAIL_ON_ERROR(dwError);
1652+ }
1653+
1654+ for (child = xmlNodeCapability->xmlChildrenNode; child; child = child->next)
1655+ {
1656+ if (child->type != XML_ELEMENT_NODE)
1657+ continue;
1658+
1659+ if (!xmlStrcmp(child->name, (const xmlChar*)"name"))
1660+ {
1661+ if (xszName)
1662+ {
1663+ dwError = APP_ERROR_XML_DUPLICATED_ELEMENT;
1664+ BAIL_ON_ERROR(dwError);
1665+ }
1666+ xszName = xmlNodeListGetString(
1667+ xmlDoc,
1668+ child->xmlChildrenNode,
1669+ TRUE);
1670+ }
1671+ else if (!xmlStrcmp(child->name, (const xmlChar*)"description"))
1672+ {
1673+ if (xszDescription)
1674+ {
1675+ dwError = APP_ERROR_XML_DUPLICATED_ELEMENT;
1676+ BAIL_ON_ERROR(dwError);
1677+ }
1678+ xszDescription = xmlNodeListGetString(
1679+ xmlDoc,
1680+ child->xmlChildrenNode,
1681+ TRUE);
1682+ }
1683+ else if (!xmlStrcmp(child->name, (const xmlChar*)"registry"))
1684+ {
1685+ if (pRegistry)
1686+ {
1687+ dwError = APP_ERROR_XML_DUPLICATED_ELEMENT;
1688+ BAIL_ON_ERROR(dwError);
1689+ }
1690+ dwError = RegistryAllocate(xmlDoc, child, &pRegistry);
1691+ BAIL_ON_ERROR(dwError);
1692+ }
1693+ }
1694+
1695+ if (!xszName || xszName[0] == '\0')
1696+ {
1697+ fprintf(stderr, "Improper format: Element 'name' not found or empty.\n");
1698+ dwError = APP_ERROR_XML_MISSING_ELEMENT;
1699+ BAIL_ON_ERROR(dwError);
1700+ }
1701+
1702+ dwError = LwAllocateString((char*)xszName, &pszName);
1703+ BAIL_ON_ERROR(dwError);
1704+
1705+ if (xszDescription)
1706+ {
1707+ dwError = LwAllocateString((char*)xszDescription, &pszDescription);
1708+ BAIL_ON_ERROR(dwError);
1709+ }
1710+
1711+ dwError = LwAllocateMemory(sizeof(*pCapability), (PVOID*)&pCapability);
1712+ BAIL_ON_ERROR(dwError);
1713+
1714+ pCapability->xmlDoc = xmlDoc;
1715+
1716+ pCapability->xmlNodeCapability = xmlNodeCapability;
1717+
1718+ pCapability->pszName = pszName;
1719+ pszName = NULL;
1720+
1721+ pCapability->pszDescription = pszDescription;
1722+ pszDescription = NULL;
1723+
1724+ pCapability->pRegistry = pRegistry;
1725+ pRegistry = NULL;
1726+
1727+ *ppCapability = pCapability;
1728+
1729+cleanup:
1730+ xmlFree(xszName);
1731+ xmlFree(xszDescription);
1732+ return dwError;
1733+
1734+error:
1735+
1736+ LW_SAFE_FREE_STRING(pszName);
1737+ LW_SAFE_FREE_STRING(pszDescription);
1738+ RegistryFree(pRegistry);
1739+ CapabilityFree(pCapability);
1740+ goto cleanup;
1741+}
1742+
1743+void
1744+CapabilityFree(
1745+ PCAPABILITY pCapability
1746+ )
1747+{
1748+ if (pCapability)
1749+ {
1750+ RegistryFree(pCapability->pRegistry);
1751+ LW_SAFE_FREE_MEMORY(pCapability->pszName);
1752+ LW_SAFE_FREE_MEMORY(pCapability->pszDescription);
1753+ LW_SAFE_FREE_MEMORY(pCapability);
1754+ }
1755+}
1756+
1757+/*
1758+ If pszName matches exactly one item, use that.
1759+ Else if pszName matches more than one item exactly, report an error.
1760+ Else if pszName is prefix matches exactly one item, use that.
1761+ Else if pszName prefix matches more than one item, print the matches and
1762+ report an error.
1763+*/
1764+DWORD
1765+CapabilityFindByName(
1766+ xmlDocPtr xmlDoc,
1767+ PCSTR pszName,
1768+ PCAPABILITY *ppCapability
1769+ )
1770+{
1771+ DWORD dwError = 0;
1772+
1773+ xmlXPathContextPtr xpathCtx = NULL;
1774+ xmlXPathObjectPtr xpathObj = NULL;
1775+ xmlNodeSetPtr nodes = NULL; // Convienence pointer
1776+ xmlNodePtr xmlNodeCapability = NULL;
1777+ PCAPABILITY pCapability = NULL;
1778+ DWORD dwNameLength = 0;
1779+ BOOLEAN bNameMatchesMany = FALSE;
1780+ BOOLEAN bNameMatchesExactly = FALSE;
1781+ size_t i;
1782+ xmlNodePtr child = NULL;
1783+ xmlChar *xszName = NULL;
1784+
1785+ dwNameLength = strlen(pszName); // Calculate once
1786+
1787+ xpathCtx = xmlXPathNewContext(xmlDoc);
1788+ if (!xpathCtx)
1789+ {
1790+ dwError = ERROR_OUTOFMEMORY;
1791+ BAIL_ON_ERROR(dwError);
1792+ }
1793+
1794+ xpathObj = xmlXPathEvalExpression(
1795+ (const xmlChar*)"/capabilities/section/capability",
1796+ xpathCtx);
1797+ if (!xpathObj)
1798+ {
1799+ dwError = APP_ERROR_XPATH_EVAL_FAILED;
1800+ BAIL_ON_ERROR(dwError);
1801+ }
1802+
1803+ nodes = xpathObj->nodesetval;
1804+ for (i = 0; i < nodes->nodeNr; i++)
1805+ {
1806+ if (nodes->nodeTab[i]->type != XML_ELEMENT_NODE)
1807+ continue;
1808+
1809+ if (xmlStrcmp((const xmlChar*)"capability", nodes->nodeTab[i]->name))
1810+ continue;
1811+
1812+ child = FindNext(nodes->nodeTab[i]->xmlChildrenNode, "name");
1813+ if (!child)
1814+ continue;
1815+
1816+ xszName = xmlNodeListGetString(xmlDoc, child->xmlChildrenNode, TRUE);
1817+ if (!xszName)
1818+ {
1819+ dwError = ERROR_OUTOFMEMORY;
1820+ BAIL_ON_ERROR(dwError);
1821+ }
1822+
1823+ if (!xmlStrcasecmp(xszName, (const xmlChar*)pszName))
1824+ {
1825+ if (bNameMatchesExactly)
1826+ {
1827+ dwError = APP_ERROR_XML_DUPLICATED_ELEMENT;
1828+ BAIL_ON_ERROR(dwError);
1829+ }
1830+
1831+ xmlNodeCapability = nodes->nodeTab[i];
1832+ bNameMatchesExactly = TRUE;
1833+ }
1834+ else if (!xmlStrncasecmp(xszName, (const xmlChar*) pszName, dwNameLength))
1835+ {
1836+ if (!bNameMatchesExactly)
1837+ {
1838+ if (xmlNodeCapability)
1839+ {
1840+ bNameMatchesMany = TRUE;
1841+ }
1842+ else
1843+ {
1844+ xmlNodeCapability = nodes->nodeTab[i];
1845+ }
1846+ }
1847+ }
1848+
1849+ xmlFree(xszName);
1850+ xszName = NULL;
1851+ }
1852+
1853+ if (!bNameMatchesExactly && bNameMatchesMany)
1854+ {
1855+ fprintf(stderr, "%s partially matches:\n", pszName);
1856+ for (i = 0; i < nodes->nodeNr; i++)
1857+ {
1858+ if (nodes->nodeTab[i]->type != XML_ELEMENT_NODE)
1859+ continue;
1860+
1861+ if (xmlStrcmp((const xmlChar*)"capability", nodes->nodeTab[i]->name))
1862+ continue;
1863+
1864+ child = FindNext(nodes->nodeTab[i]->xmlChildrenNode, "name");
1865+ if (!child)
1866+ continue;
1867+
1868+
1869+ xszName = xmlNodeListGetString(xmlDoc, child->xmlChildrenNode, TRUE);
1870+ if (!xszName)
1871+ {
1872+ dwError = ERROR_OUTOFMEMORY;
1873+ BAIL_ON_ERROR(dwError);
1874+ }
1875+
1876+ if (!xmlStrncasecmp(xszName, (const xmlChar*)pszName, dwNameLength))
1877+ {
1878+ fprintf(stderr, "%s\n", (PCSTR)xszName);
1879+ }
1880+
1881+ xmlFree(xszName);
1882+ xszName = NULL;
1883+ }
1884+ dwError = APP_ERROR_CAPABILITY_MULTIPLE_MATCHES;
1885+ BAIL_ON_ERROR(dwError);
1886+ }
1887+ else if (!xmlNodeCapability)
1888+ {
1889+ dwError = APP_ERROR_CAPABILITY_NOT_FOUND;
1890+ BAIL_ON_ERROR(dwError);
1891+ }
1892+
1893+ dwError = CapabilityAllocate(xmlDoc, xmlNodeCapability, &pCapability);
1894+ BAIL_ON_ERROR(dwError);
1895+
1896+ *ppCapability = pCapability;
1897+
1898+cleanup:
1899+
1900+ xmlXPathFreeObject(xpathObj);
1901+ xmlXPathFreeContext(xpathCtx);
1902+
1903+ xmlFree(xszName);
1904+ xszName = NULL;
1905+
1906+ return dwError;
1907+
1908+error:
1909+
1910+ CapabilityFree(pCapability);
1911+ goto cleanup;
1912+}
1913+
1914+static
1915+DWORD
1916+ValidateString(
1917+ PCSTR pszValue,
1918+ xmlDocPtr xmlDoc,
1919+ xmlNodePtr pxRegistry,
1920+ PBOOLEAN pbAccept
1921+ )
1922+{
1923+ DWORD dwError = 0;
1924+ xmlNodePtr xmlAccept = NULL;
1925+ xmlNodePtr xmlAcceptChild = NULL;
1926+ const DWORD UNDECIDED = 0;
1927+ const DWORD ACCEPT_VALUE = 1;
1928+ const DWORD REJECT_VALUE = 2;
1929+ DWORD dwDecision = UNDECIDED;
1930+ const DWORD NOTHING = 0;
1931+ const DWORD ACCEPT = 1;
1932+ const DWORD REJECT = 2;
1933+ DWORD dwState = NOTHING;
1934+ xmlChar *xszValue = NULL;
1935+ xmlChar *xszPattern = NULL;
1936+ regex_t patternExp;
1937+ regmatch_t matches[5];
1938+
1939+
1940+ for (xmlAccept = pxRegistry->xmlChildrenNode;
1941+ xmlAccept && dwDecision == UNDECIDED;
1942+ xmlAccept = xmlAccept->next)
1943+ {
1944+ if (xmlAccept->type != XML_ELEMENT_NODE)
1945+ continue;
1946+
1947+ if (!xmlStrcmp(xmlAccept->name, (const xmlChar*)"accept"))
1948+ {
1949+ dwState = ACCEPT;
1950+ }
1951+ else if (!xmlStrcmp(xmlAccept->name, (const xmlChar*)"reject"))
1952+ {
1953+ dwState = REJECT;
1954+ }
1955+ else
1956+ {
1957+ continue;
1958+ }
1959+
1960+ for (xmlAcceptChild = xmlAccept->xmlChildrenNode;
1961+ xmlAcceptChild && dwDecision == UNDECIDED;
1962+ xmlAcceptChild = xmlAcceptChild->next)
1963+ {
1964+ if (xmlAcceptChild->type != XML_ELEMENT_NODE)
1965+ continue;
1966+
1967+ if (!xmlStrcmp(xmlAcceptChild->name, (const xmlChar*)"value"))
1968+ {
1969+ xszValue = xmlNodeListGetString(
1970+ xmlDoc,
1971+ xmlAcceptChild->xmlChildrenNode,
1972+ TRUE);
1973+ if (xszValue && !strcmp((PCSTR)xszValue, pszValue))
1974+ {
1975+ if (dwState == ACCEPT)
1976+ {
1977+ dwDecision = ACCEPT_VALUE;
1978+ }
1979+ else
1980+ {
1981+ dwDecision = REJECT_VALUE;
1982+ }
1983+ }
1984+ if (xszValue)
1985+ {
1986+ xmlFree(xszValue);
1987+ xszValue = NULL;
1988+ }
1989+
1990+ } else if (!xmlStrcmp(
1991+ xmlAcceptChild->name,
1992+ (const xmlChar*)"pattern"))
1993+ {
1994+ xszPattern = xmlNodeListGetString(
1995+ xmlDoc,
1996+ xmlAcceptChild->xmlChildrenNode,
1997+ TRUE);
1998+
1999+ if (xszPattern)
2000+ {
2001+ if (!regcomp(&patternExp, (PCSTR)xszPattern, REG_EXTENDED))
2002+ {
2003+ if (!regexec(&patternExp, pszValue,
2004+ sizeof(matches)/sizeof(matches[0]),
2005+ matches,
2006+ 0))
2007+ {
2008+ if (dwState == ACCEPT)
2009+ {
2010+ dwDecision = ACCEPT_VALUE;
2011+ }
2012+ else
2013+ {
2014+ dwDecision = REJECT_VALUE;
2015+ }
2016+ }
2017+ regfree(&patternExp);
2018+ }
2019+ }
2020+ if (xszPattern)
2021+ {
2022+ xmlFree(xszPattern);
2023+ xszPattern = NULL;
2024+ }
2025+ }
2026+ }
2027+ }
2028+
2029+ if (dwDecision == ACCEPT_VALUE)
2030+ {
2031+ *pbAccept = TRUE;
2032+ }
2033+ else if (dwDecision == REJECT_VALUE)
2034+ {
2035+ *pbAccept = FALSE;
2036+ }
2037+ else
2038+ {
2039+ if (dwState == NOTHING)
2040+ {
2041+ *pbAccept = TRUE;
2042+ }
2043+ else if (dwState == ACCEPT)
2044+ {
2045+ *pbAccept = FALSE;
2046+ }
2047+ else if (dwState == REJECT)
2048+ {
2049+ *pbAccept = TRUE;
2050+ }
2051+ }
2052+
2053+ if (xszValue)
2054+ {
2055+ xmlFree(xszValue);
2056+ xszValue = NULL;
2057+ }
2058+ if (xszPattern)
2059+ {
2060+ xmlFree(xszPattern);
2061+ xszPattern = NULL;
2062+ }
2063+
2064+ return dwError;
2065+}
2066+
2067+static
2068+DWORD
2069+CapabilityRegistryGetUnitMultiplier(
2070+ PCSTR pszUnit,
2071+ xmlNodePtr pxRegistry,
2072+ PBOOLEAN pbMatched,
2073+ PDWORD pdwMultiplier,
2074+ PDWORD pdwDivisor
2075+ )
2076+{
2077+ DWORD dwError = 0;
2078+ xmlChar* xszUnitSuffix = NULL;
2079+ xmlChar* xszUnitMultiplier = NULL;
2080+ xmlChar* xszUnitDivisor = NULL;
2081+ DWORD dwUnitMultiplier = 1;
2082+ DWORD dwUnitDivisor = 1;
2083+ xmlNodePtr child = NULL;
2084+
2085+ if (pxRegistry)
2086+ child = pxRegistry->xmlChildrenNode;
2087+ for (; child; child = child->next)
2088+ {
2089+ if (child->type != XML_ELEMENT_NODE)
2090+ continue;
2091+
2092+ if (!xmlStrcmp(child->name, (const xmlChar*)"unit"))
2093+ {
2094+ xszUnitSuffix = xmlGetProp(child, (const xmlChar*)"suffix");
2095+ if (xszUnitSuffix && !strcmp((PCSTR)xszUnitSuffix, pszUnit))
2096+ break;
2097+ }
2098+ }
2099+
2100+ if (child)
2101+ xszUnitMultiplier = xmlGetProp(child, (const xmlChar*)"multiplier");
2102+ if (xszUnitMultiplier)
2103+ {
2104+ dwUnitMultiplier = strtol((PCSTR)xszUnitMultiplier, NULL, 10);
2105+ }
2106+
2107+ if (child)
2108+ xszUnitDivisor = xmlGetProp(child, (xmlChar*)"divisor");
2109+ if (xszUnitDivisor)
2110+ {
2111+ dwUnitDivisor = strtol((PCSTR)xszUnitDivisor, NULL, 10);
2112+ }
2113+
2114+ *pdwMultiplier = dwUnitMultiplier;
2115+ *pdwDivisor = dwUnitDivisor;
2116+ *pbMatched = TRUE;
2117+
2118+ xmlFree(xszUnitSuffix);
2119+ xszUnitSuffix = NULL;
2120+
2121+ xmlFree(xszUnitMultiplier);
2122+ xszUnitMultiplier = NULL;
2123+
2124+ xmlFree(xszUnitDivisor);
2125+ xszUnitDivisor = NULL;
2126+
2127+ return dwError;
2128+}
2129+
2130+static
2131+DWORD
2132+CapabilityNormalizeDword(
2133+ PCSTR pszValue,
2134+ xmlNodePtr pxRegistry,
2135+ PDWORD pdwValue
2136+ )
2137+{
2138+ DWORD dwError = 0;
2139+ PSTR pszEndChar = NULL; /* Don't free */
2140+ BOOLEAN bMatched = FALSE;
2141+ DWORD dwValue = 0;
2142+
2143+ dwValue = strtol(pszValue, &pszEndChar, 10);
2144+ if (dwValue == 0 && pszValue == pszEndChar)
2145+ {
2146+ fprintf(
2147+ stderr,
2148+ "Invalid parameter '%s': could not interpret as dword\n",
2149+ pszValue);
2150+ dwError = APP_ERROR_INVALID_DWORD;
2151+ BAIL_ON_ERROR(dwError);
2152+ }
2153+
2154+ // Left over characters indicate a suffix -- look for element 'unit'.
2155+ if (pszEndChar && *pszEndChar != '\0')
2156+ {
2157+ DWORD dwUnitMultiplier = 1;
2158+ DWORD dwUnitDivisor = 1;
2159+
2160+ dwError = CapabilityRegistryGetUnitMultiplier(
2161+ pszEndChar,
2162+ pxRegistry,
2163+ &bMatched,
2164+ &dwUnitMultiplier,
2165+ &dwUnitDivisor);
2166+ BAIL_ON_ERROR(dwError);
2167+
2168+ if (!bMatched)
2169+ {
2170+ fprintf(stderr, "Invalid parameter '%s': could not interpret %s\n",
2171+ pszValue, pszEndChar);
2172+ dwError = APP_ERROR_INVALID_SUFFIX;
2173+ BAIL_ON_ERROR(dwError);
2174+ }
2175+
2176+
2177+ dwValue = dwValue * dwUnitMultiplier;
2178+ dwValue = dwValue / dwUnitDivisor;
2179+ }
2180+
2181+ *pdwValue = dwValue;
2182+
2183+cleanup:
2184+
2185+ return dwError;
2186+
2187+error:
2188+
2189+ goto cleanup;
2190+}
2191+
2192+static
2193+DWORD
2194+ValidateDword(
2195+ DWORD dwValue,
2196+ xmlNodePtr pxRegistry,
2197+ PBOOLEAN pbAccept
2198+ )
2199+{
2200+ DWORD dwError = 0;
2201+ xmlNodePtr xmlAccept = NULL;
2202+ xmlNodePtr xmlRange = NULL;
2203+ xmlChar *xszMin = NULL;
2204+ xmlChar *xszMax = NULL;
2205+ DWORD dwMin = 0;
2206+ DWORD dwMax = 0;
2207+ const DWORD UNDECIDED = 0;
2208+ const DWORD ACCEPT_VALUE = 1;
2209+ const DWORD REJECT_VALUE = 2;
2210+ DWORD dwDecision = UNDECIDED;
2211+ const DWORD NOTHING = 0;
2212+ const DWORD ACCEPT = 1;
2213+ const DWORD REJECT = 2;
2214+ DWORD dwState = NOTHING;
2215+
2216+ for (xmlAccept = pxRegistry->xmlChildrenNode;
2217+ xmlAccept && dwDecision == UNDECIDED;
2218+ xmlAccept = xmlAccept->next)
2219+ {
2220+ if (xmlAccept->type != XML_ELEMENT_NODE)
2221+ continue;
2222+
2223+ if (!xmlStrcmp(xmlAccept->name, (const xmlChar*)"accept"))
2224+ {
2225+ dwState = ACCEPT;
2226+ }
2227+ else if (!xmlStrcmp(xmlAccept->name, (const xmlChar*)"reject"))
2228+ {
2229+ dwState = REJECT;
2230+ }
2231+ else
2232+ {
2233+ continue;
2234+ }
2235+
2236+ for (xmlRange = xmlAccept->xmlChildrenNode;
2237+ xmlRange && dwDecision == UNDECIDED;
2238+ xmlRange = xmlRange->next)
2239+ {
2240+ if (xmlRange->type != XML_ELEMENT_NODE)
2241+ continue;
2242+
2243+ if (!xmlStrcmp(xmlRange->name, (const xmlChar*)"range"))
2244+ {
2245+ xszMin = xmlGetProp(xmlRange, (const xmlChar*)"min");
2246+ xszMax = xmlGetProp(xmlRange, (const xmlChar*)"max");
2247+
2248+ dwError = CapabilityNormalizeDword(
2249+ (PCSTR)xszMin,
2250+ pxRegistry,
2251+ &dwMin);
2252+ BAIL_ON_ERROR(dwError);
2253+
2254+ dwError = CapabilityNormalizeDword(
2255+ (PCSTR)xszMax,
2256+ pxRegistry,
2257+ &dwMax);
2258+ BAIL_ON_ERROR(dwError);
2259+
2260+ if (dwMin <= dwValue && dwValue <= dwMax)
2261+ {
2262+ if (dwState == ACCEPT)
2263+ {
2264+ dwDecision = ACCEPT_VALUE;
2265+ }
2266+ else
2267+ dwDecision = REJECT_VALUE;
2268+ }
2269+
2270+ if (xszMin)
2271+ {
2272+ xmlFree(xszMin);
2273+ xszMin = NULL;
2274+ }
2275+ if (xszMax)
2276+ {
2277+ xmlFree(xszMax);
2278+ xszMax = NULL;
2279+ }
2280+ }
2281+ }
2282+ }
2283+
2284+ if (dwDecision == ACCEPT_VALUE)
2285+ {
2286+ *pbAccept = TRUE;
2287+ }
2288+ else if (dwDecision == REJECT_VALUE)
2289+ {
2290+ *pbAccept = FALSE;
2291+ }
2292+ else
2293+ {
2294+ if (dwState == NOTHING)
2295+ {
2296+ *pbAccept = TRUE;
2297+ }
2298+ else if (dwState == ACCEPT)
2299+ {
2300+ *pbAccept = FALSE;
2301+ }
2302+ else if (dwState == REJECT)
2303+ {
2304+ *pbAccept = TRUE;
2305+ }
2306+ }
2307+
2308+cleanup:
2309+
2310+ if (xszMin)
2311+ {
2312+ xmlFree(xszMin);
2313+ xszMin = NULL;
2314+ }
2315+ if (xszMax)
2316+ {
2317+ xmlFree(xszMax);
2318+ xszMax = NULL;
2319+ }
2320+ return dwError;
2321+
2322+error:
2323+ goto cleanup;
2324+}
2325+
2326+static
2327+DWORD
2328+CapabilityNormalizeBoolean(
2329+ PCSTR pszValue,
2330+ PDWORD pdwValue
2331+ )
2332+{
2333+ DWORD dwError = 0;
2334+ DWORD dwValue = 0;
2335+
2336+ if (!strcasecmp("true", pszValue) ||
2337+ !strcasecmp("1", pszValue))
2338+ {
2339+ dwValue = 1;
2340+ }
2341+ else if (!strcasecmp("false", pszValue) ||
2342+ !strcasecmp("0", pszValue))
2343+ {
2344+ dwValue = 0;
2345+ }
2346+ else
2347+ {
2348+ fprintf(stderr, "Invalid parameter: Cannot interpret '%s' as boolean\n",
2349+ pszValue);
2350+ dwError = APP_ERROR_INVALID_BOOLEAN;
2351+ BAIL_ON_ERROR(dwError);
2352+ }
2353+
2354+ *pdwValue = dwValue;
2355+
2356+cleanup:
2357+ return dwError;
2358+
2359+error:
2360+ goto cleanup;
2361+}
2362+
2363+DWORD
2364+DefaultValue(
2365+ xmlDocPtr xmlDoc,
2366+ xmlNodePtr pxDefault,
2367+ PSTR *ppszValue
2368+ )
2369+{
2370+ DWORD dwError = 0;
2371+ xmlNodePtr child = NULL;
2372+ xmlChar *xszDefault = NULL;
2373+ DWORD dwLength = 0;
2374+ PSTR pszValue = NULL;
2375+
2376+ if (pxDefault->type != XML_ELEMENT_NODE)
2377+ {
2378+ dwError = ERROR_INVALID_PARAMETER;
2379+ BAIL_ON_ERROR(dwError);
2380+ }
2381+
2382+ dwLength = 0;
2383+ for (child = pxDefault->xmlChildrenNode; child; child = child->next)
2384+ {
2385+ if (child->type != XML_ELEMENT_NODE)
2386+ continue;
2387+
2388+ if (!xmlStrcmp(child->name, (const xmlChar*)"value"))
2389+ {
2390+ xszDefault = xmlNodeListGetString(
2391+ xmlDoc,
2392+ child->xmlChildrenNode,
2393+ TRUE);
2394+
2395+ if (xszDefault)
2396+ dwLength += strlen((PSTR)xszDefault);
2397+ dwLength += 1;
2398+
2399+ xmlFree(xszDefault);
2400+ xszDefault = NULL;
2401+ }
2402+ }
2403+ dwLength += 1;
2404+
2405+ dwError = LwAllocateMemory(dwLength, (PVOID*)&pszValue);
2406+ BAIL_ON_ERROR(dwError);
2407+
2408+ dwLength = 0;
2409+ for (child = pxDefault->xmlChildrenNode; child; child = child->next)
2410+ {
2411+ if (child->type != XML_ELEMENT_NODE)
2412+ continue;
2413+
2414+ if (!xmlStrcmp(child->name, (xmlChar*)"value"))
2415+ {
2416+ xszDefault = xmlNodeListGetString(
2417+ xmlDoc,
2418+ child->xmlChildrenNode,
2419+ TRUE);
2420+ if (xszDefault)
2421+ {
2422+ strcpy(pszValue + dwLength, (PSTR)xszDefault);
2423+ dwLength += strlen((PSTR)xszDefault);
2424+ }
2425+ pszValue[dwLength] = '\0';
2426+ dwLength += 1;
2427+
2428+ xmlFree(xszDefault);
2429+ xszDefault = NULL;
2430+ }
2431+ }
2432+
2433+ *ppszValue = pszValue;
2434+
2435+cleanup:
2436+ xmlFree(xszDefault);
2437+ xszDefault = NULL;
2438+
2439+ return dwError;
2440+
2441+error:
2442+ LW_SAFE_FREE_MEMORY(pszValue);
2443+ goto cleanup;
2444+}
2445+
2446+DWORD
2447+CapabilityEditRegistry(
2448+ PCAPABILITY pCapability,
2449+ PCSTR pszaArg,
2450+ BOOLEAN bVerbose
2451+ )
2452+{
2453+ DWORD dwError = 0;
2454+ DWORD dwValue = 0;
2455+ PREGISTRY pRegistry = NULL;
2456+ DWORD dwType = -1;
2457+ const BYTE *pData = NULL;
2458+ DWORD dwDataSize = 0;
2459+ PSTR pszRoot = NULL;
2460+ PSTR pszKey = NULL;
2461+ PSTR pszName = NULL;
2462+ PSTR pszaValue = NULL;
2463+ PCSTR pszValue = NULL;
2464+ BOOLEAN bUsingDefault = FALSE;
2465+ BOOLEAN bAccept = FALSE;
2466+
2467+ if (!pCapability)
2468+ {
2469+ dwError = ERROR_INVALID_PARAMETER;
2470+ BAIL_ON_ERROR(dwError);
2471+ }
2472+
2473+ if (!pCapability->pRegistry)
2474+ {
2475+ goto cleanup;
2476+ }
2477+
2478+ pRegistry = pCapability->pRegistry;
2479+
2480+ if (pszaArg == NULL)
2481+ {
2482+ if (!pRegistry->pszaDefault)
2483+ {
2484+ fprintf(stderr, "Error: No parameter specified and no default value exist.\n");
2485+ dwError = APP_ERROR_PARAMETER_REQUIRED;
2486+ BAIL_ON_ERROR(dwError);
2487+ }
2488+ else
2489+ {
2490+ pszaArg = pRegistry->pszaDefault;
2491+ bUsingDefault = TRUE;
2492+ }
2493+ }
2494+
2495+ if (!strcmp(pRegistry->pszType, "string"))
2496+ {
2497+ dwError = ValidateString(pszaArg, pCapability->xmlDoc, pRegistry->pxRegistry, &bAccept);
2498+ BAIL_ON_ERROR(dwError);
2499+
2500+ if (!bAccept)
2501+ {
2502+ dwError = APP_ERROR_VALUE_NOT_ACCEPTED;
2503+ BAIL_ON_ERROR(dwError);
2504+ }
2505+ dwType = REG_SZ;
2506+ pData = (const BYTE*) pszaArg;
2507+ dwDataSize = strlen(pszaArg) + 1;
2508+ }
2509+ else if (!strcmp(pRegistry->pszType, "multistring"))
2510+ {
2511+ dwType = REG_MULTI_SZ;
2512+ pData = (const BYTE*) pszaArg;
2513+ dwDataSize = UtilMultistringLength(pszaArg);
2514+ }
2515+ else if (!strcmp(pRegistry->pszType, "dword"))
2516+ {
2517+ dwError = CapabilityNormalizeDword(pszaArg, pRegistry->pxRegistry, &dwValue);
2518+ BAIL_ON_ERROR(dwError);
2519+
2520+ dwError = ValidateDword(dwValue, pRegistry->pxRegistry, &bAccept);
2521+ BAIL_ON_ERROR(dwError);
2522+
2523+ if (!bAccept)
2524+ {
2525+ dwError = APP_ERROR_VALUE_NOT_ACCEPTED;
2526+ BAIL_ON_ERROR(dwError);
2527+ }
2528+
2529+ dwType = REG_DWORD;
2530+ pData = (const BYTE*) &dwValue;
2531+ dwDataSize = sizeof(dwValue);
2532+ }
2533+ else if (!strcmp(pRegistry->pszType, "boolean"))
2534+ {
2535+ dwError = CapabilityNormalizeBoolean(pszaArg, &dwValue);
2536+ BAIL_ON_ERROR(dwError);
2537+
2538+ dwType = REG_DWORD;
2539+ pData = (const BYTE*) &dwValue;
2540+ dwDataSize = sizeof(dwValue);
2541+ }
2542+ else
2543+ {
2544+ fprintf(stderr, "Unknown input type '%s'\n", pRegistry->pszType);
2545+ dwError = APP_ERROR_UNKNOWN_TYPE;
2546+ BAIL_ON_ERROR(dwError);
2547+ }
2548+
2549+ if (bVerbose)
2550+ {
2551+ dwError = GetLocalPolicyValue(pCapability, &pszaValue);
2552+ BAIL_ON_ERROR(dwError);
2553+
2554+ fprintf(stdout, "Current local policy value(s): ");
2555+ if (pszaValue[0] == '\0')
2556+ {
2557+ fprintf(stdout, "\n");
2558+ }
2559+ else
2560+ {
2561+ for (pszValue = pszaValue;
2562+ *pszValue;
2563+ pszValue = pszValue + strlen(pszValue) + 1)
2564+ {
2565+ fprintf(stdout, "%s\n", pszValue);
2566+ }
2567+ }
2568+ }
2569+
2570+ if (bVerbose && bUsingDefault)
2571+ {
2572+ fprintf(stderr, "Using default value(s): ");
2573+ if (pszaArg[0] == '\0')
2574+ {
2575+ fprintf(stdout, "\n");
2576+ }
2577+ else
2578+ {
2579+ for (pszValue = pszaArg;
2580+ *pszValue;
2581+ pszValue = pszValue + strlen(pszValue) + 1)
2582+ {
2583+ fprintf(stdout, "%s\n", pszValue);
2584+ }
2585+ }
2586+ }
2587+
2588+ dwError = UtilParseRegName(
2589+ pRegistry->pszLocalPath,
2590+ &pszRoot,
2591+ &pszKey,
2592+ &pszName);
2593+ BAIL_ON_ERROR(dwError);
2594+
2595+ dwError = UtilSetValueExA(
2596+ pszRoot,
2597+ pszKey,
2598+ pszName,
2599+ dwType,
2600+ pData,
2601+ dwDataSize);
2602+ BAIL_ON_ERROR(dwError);
2603+
2604+cleanup:
2605+
2606+ LW_SAFE_FREE_STRING(pszRoot);
2607+ LW_SAFE_FREE_STRING(pszKey);
2608+ LW_SAFE_FREE_STRING(pszName);
2609+ LW_SAFE_FREE_MEMORY(pszaValue);
2610+
2611+ return dwError;
2612+
2613+error:
2614+ goto cleanup;
2615+}
2616+
2617+DWORD
2618+CapabilityApply(
2619+ PCAPABILITY pCapability,
2620+ BOOLEAN bVerbose
2621+ )
2622+{
2623+ DWORD dwError = 0;
2624+ PREGISTRY pRegistry = NULL;
2625+ xmlNodePtr child = NULL;
2626+ xmlChar *xszCommand = NULL;
2627+ PSTR pszCommand = NULL;
2628+ int ret = 0;
2629+
2630+ if (!pCapability)
2631+ {
2632+ dwError = ERROR_INVALID_PARAMETER;
2633+ BAIL_ON_ERROR(dwError);
2634+ }
2635+
2636+ if (!pCapability->pRegistry)
2637+ {
2638+ goto cleanup;
2639+ }
2640+
2641+ pRegistry = pCapability->pRegistry;
2642+
2643+ for (child = pRegistry->pxRegistry->xmlChildrenNode; child; child =
2644+ child->next)
2645+ {
2646+ if (child->type != XML_ELEMENT_NODE)
2647+ continue;
2648+
2649+ if (!xmlStrcmp(child->name, (const xmlChar*) "apply"))
2650+ {
2651+ xszCommand = xmlGetProp(child, (const xmlChar*)"command");
2652+ if (xszCommand)
2653+ {
2654+ if (bVerbose)
2655+ {
2656+ dwError = LwAllocateStringPrintf(
2657+ &pszCommand,
2658+ "%s",
2659+ (PCSTR)xszCommand);
2660+ }
2661+ else
2662+ {
2663+ dwError = LwAllocateStringPrintf(
2664+ &pszCommand,
2665+ "%s >/dev/null 2>/dev/null",
2666+ (PCSTR)xszCommand);
2667+ }
2668+ BAIL_ON_ERROR(dwError);
2669+
2670+ if (bVerbose)
2671+ fprintf(stdout, "Executing command: %s\n", pszCommand);
2672+
2673+ ret = system((PCSTR)pszCommand);
2674+ if (ret == -1)
2675+ {
2676+ fprintf(stderr, "Problem executing '%s'\n", pszCommand);
2677+ dwError = APP_ERROR_COULD_NOT_FORK;
2678+ }
2679+ else if (ret > 0)
2680+ {
2681+ fprintf(stderr, "Problem executing '%s'\n", pszCommand);
2682+ dwError = APP_ERROR_PROGRAM_ERROR;
2683+ }
2684+
2685+ xmlFree(xszCommand);
2686+ xszCommand = NULL;
2687+
2688+ LW_SAFE_FREE_STRING(pszCommand);
2689+ }
2690+ }
2691+ }
2692+
2693+cleanup:
2694+ LW_SAFE_FREE_STRING(pszCommand);
2695+ xmlFree(xszCommand);
2696+ return dwError;
2697+
2698+error:
2699+ goto cleanup;
2700+}
2701+
2702+static
2703+DWORD
2704+GetLocalPolicyValue(
2705+ PCAPABILITY pCapability,
2706+ PSTR *ppszaValue
2707+ )
2708+{
2709+ DWORD dwError = 0;
2710+ PREGISTRY pRegistry = NULL;
2711+ DWORD dwType = -1;
2712+ const BYTE *pData = NULL;
2713+ DWORD dwDataSize = 0;
2714+ PSTR pszRoot = NULL;
2715+ PSTR pszKey = NULL;
2716+ PSTR pszName = NULL;
2717+ DWORD dwValue = 0;
2718+ PSTR pszaArg = NULL;
2719+ PSTR pszaValue = NULL;
2720+ PSTR pszBuf = NULL;
2721+
2722+ if (!pCapability)
2723+ {
2724+ dwError = ERROR_INVALID_PARAMETER;
2725+ BAIL_ON_ERROR(dwError);
2726+ }
2727+
2728+ if (!pCapability->pRegistry)
2729+ {
2730+ goto cleanup;
2731+ }
2732+
2733+ pRegistry = pCapability->pRegistry;
2734+
2735+ if (!strcmp(pRegistry->pszType, "string"))
2736+ {
2737+ dwType = REG_SZ;
2738+ pData = (const BYTE*) &pszaArg;
2739+ dwDataSize = 0;
2740+ }
2741+ else if (!strcmp(pRegistry->pszType, "multistring"))
2742+ {
2743+ dwType = REG_MULTI_SZ;
2744+ pData = (const BYTE*) &pszaArg;
2745+ dwDataSize = 0;
2746+ }
2747+ else if (!strcmp(pRegistry->pszType, "dword"))
2748+ {
2749+ dwType = REG_DWORD;
2750+ pData = (const BYTE*) &dwValue;
2751+ dwDataSize = sizeof(dwValue);
2752+ }
2753+ else if (!strcmp(pRegistry->pszType, "boolean"))
2754+ {
2755+ dwType = REG_DWORD;
2756+ pData = (const BYTE*) &dwValue;
2757+ dwDataSize = sizeof(dwValue);
2758+ }
2759+ else
2760+ {
2761+ fprintf(stderr, "Unknown input type '%s'\n", pRegistry->pszType);
2762+ dwError = APP_ERROR_UNKNOWN_TYPE;
2763+ BAIL_ON_ERROR(dwError);
2764+ }
2765+
2766+ dwError = UtilParseRegName(
2767+ pRegistry->pszLocalPath,
2768+ &pszRoot,
2769+ &pszKey,
2770+ &pszName);
2771+ BAIL_ON_ERROR(dwError);
2772+
2773+ dwError = UtilGetValueExA(
2774+ pszRoot,
2775+ pszKey,
2776+ pszName,
2777+ dwType,
2778+ (PVOID)pData,
2779+ &dwDataSize);
2780+ BAIL_ON_ERROR(dwError);
2781+
2782+ if (!strcmp(pRegistry->pszType, "boolean"))
2783+ {
2784+ PCSTR pszTrue = "true";
2785+ PCSTR pszFalse = "false";
2786+ dwError = UtilAllocateMultistring(
2787+ dwValue ? &pszTrue : &pszFalse,
2788+ 1,
2789+ &pszaValue);
2790+ BAIL_ON_ERROR(dwError);
2791+ }
2792+ else if (dwType == REG_DWORD)
2793+ {
2794+ dwError = LwAllocateStringPrintf(
2795+ &pszBuf,
2796+ "%lu",
2797+ (unsigned long) dwValue);
2798+ dwError = UtilAllocateMultistring((PCSTR*)&pszBuf, 1, &pszaValue);
2799+ BAIL_ON_ERROR(dwError);
2800+ }
2801+ else if (dwType == REG_SZ)
2802+ {
2803+ dwError = UtilAllocateMultistring((PCSTR*)&pszaArg, 1, &pszaValue);
2804+ BAIL_ON_ERROR(dwError);
2805+ }
2806+ else if (dwType == REG_MULTI_SZ)
2807+ {
2808+ dwError = UtilDuplicateMultistring(pszaArg, &pszaValue);
2809+ BAIL_ON_ERROR(dwError);
2810+ }
2811+
2812+ *ppszaValue = pszaValue;
2813+
2814+cleanup:
2815+
2816+ LW_SAFE_FREE_STRING(pszRoot);
2817+ LW_SAFE_FREE_STRING(pszKey);
2818+ LW_SAFE_FREE_STRING(pszName);
2819+ LW_SAFE_FREE_STRING(pszaArg);
2820+ LW_SAFE_FREE_STRING(pszBuf);
2821+
2822+ return dwError;
2823+
2824+error:
2825+ LW_SAFE_FREE_MEMORY(pszaValue);
2826+ goto cleanup;
2827+
2828+}
2829+
2830+static
2831+DWORD
2832+CapabilityGetRegistry(
2833+ PREGISTRY pRegistry,
2834+ PSTR *ppszaArg,
2835+ PDWORD pdwValue,
2836+ PBOOLEAN pbLocalPolicy
2837+)
2838+{
2839+ DWORD dwError = 0;
2840+ DWORD dwType = -1;
2841+ const BYTE *pData = NULL;
2842+ DWORD dwDataSize = 0;
2843+ PSTR pszRoot = NULL;
2844+ PSTR pszKey = NULL;
2845+ PSTR pszName = NULL;
2846+ BOOLEAN bTryLocalPolicy = TRUE;
2847+
2848+ if (!strcmp(pRegistry->pszType, "string"))
2849+ {
2850+ dwType = REG_SZ;
2851+ pData = (const BYTE*) ppszaArg;
2852+ dwDataSize = 0;
2853+ }
2854+ else if (!strcmp(pRegistry->pszType, "multistring"))
2855+ {
2856+ dwType = REG_MULTI_SZ;
2857+ pData = (const BYTE*) ppszaArg;
2858+ dwDataSize = 0;
2859+ }
2860+ else if (!strcmp(pRegistry->pszType, "dword"))
2861+ {
2862+ dwType = REG_DWORD;
2863+ pData = (const BYTE*) pdwValue;
2864+ dwDataSize = sizeof(*pdwValue);
2865+ }
2866+ else if (!strcmp(pRegistry->pszType, "boolean"))
2867+ {
2868+ dwType = REG_DWORD;
2869+ pData = (const BYTE*) pdwValue;
2870+ dwDataSize = sizeof(*pdwValue);
2871+ }
2872+ else
2873+ {
2874+ fprintf(stderr, "Unknown input type '%s'\n", pRegistry->pszType);
2875+ dwError = APP_ERROR_UNKNOWN_TYPE;
2876+ BAIL_ON_ERROR(dwError);
2877+ }
2878+
2879+ if (pRegistry->pszPolicyPath)
2880+ {
2881+ dwError = UtilParseRegName(
2882+ pRegistry->pszPolicyPath,
2883+ &pszRoot,
2884+ &pszKey,
2885+ &pszName);
2886+ BAIL_ON_ERROR(dwError);
2887+
2888+ dwError = UtilGetValueExA(
2889+ pszRoot,
2890+ pszKey,
2891+ pszName,
2892+ dwType,
2893+ (PVOID) pData,
2894+ &dwDataSize);
2895+ LW_SAFE_FREE_STRING(pszRoot);
2896+ LW_SAFE_FREE_STRING(pszKey);
2897+ LW_SAFE_FREE_STRING(pszName);
2898+
2899+ if (!dwError)
2900+ {
2901+ bTryLocalPolicy = FALSE;
2902+ }
2903+ }
2904+
2905+ if (bTryLocalPolicy)
2906+ {
2907+ dwError = UtilParseRegName(
2908+ pRegistry->pszLocalPath,
2909+ &pszRoot,
2910+ &pszKey,
2911+ &pszName);
2912+ BAIL_ON_ERROR(dwError);
2913+
2914+ dwError = UtilGetValueExA(
2915+ pszRoot,
2916+ pszKey,
2917+ pszName,
2918+ dwType,
2919+ (PVOID)pData,
2920+ &dwDataSize);
2921+ BAIL_ON_ERROR(dwError);
2922+
2923+ *pbLocalPolicy = TRUE;
2924+ }
2925+
2926+error:
2927+ return dwError;
2928+}
2929+
2930+DWORD
2931+CapabilityDump(
2932+ PCAPABILITY pCapability
2933+ )
2934+{
2935+ DWORD dwError = 0;
2936+ PREGISTRY pRegistry = NULL;
2937+ DWORD dwValue = 0;
2938+ PSTR pszaArg = NULL;
2939+ PSTR pszEsc = NULL;
2940+ BOOLEAN bLocalPolicy = FALSE;
2941+
2942+ if (!pCapability)
2943+ {
2944+ dwError = ERROR_INVALID_PARAMETER;
2945+ BAIL_ON_ERROR(dwError);
2946+ }
2947+
2948+ if (!pCapability->pRegistry)
2949+ {
2950+ goto cleanup;
2951+ }
2952+
2953+ pRegistry = pCapability->pRegistry;
2954+
2955+ dwError = CapabilityGetRegistry(pRegistry, &pszaArg, &dwValue, &bLocalPolicy);
2956+ if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
2957+ {
2958+ dwError = 0;
2959+ goto cleanup;
2960+ }
2961+ BAIL_ON_ERROR(dwError);
2962+
2963+ fprintf(stdout, "%s", pCapability->pszName);
2964+ if (!strcmp(pRegistry->pszType, "boolean"))
2965+ {
2966+ fprintf(stdout, " %s\n", dwValue ? "true" : "false");
2967+ }
2968+ else if (!strcmp(pRegistry->pszType, "dword"))
2969+ {
2970+ fprintf(stdout, " %lu\n", (unsigned long)dwValue);
2971+ }
2972+ else if (!strcmp(pRegistry->pszType, "string"))
2973+ {
2974+ dwError = UtilAllocateEscapedString(pszaArg, &pszEsc);
2975+ BAIL_ON_ERROR(dwError);
2976+
2977+ fprintf(stdout, " \"%s\"\n", pszEsc);
2978+
2979+ LW_SAFE_FREE_STRING(pszEsc);
2980+ }
2981+ else if (!strcmp(pRegistry->pszType, "multistring"))
2982+ {
2983+ PCSTR pszStr = pszaArg;
2984+ while (*pszStr)
2985+ {
2986+ dwError = UtilAllocateEscapedString(pszStr, &pszEsc);
2987+ BAIL_ON_ERROR(dwError);
2988+
2989+ fprintf(stdout, " \"%s\"", pszEsc);
2990+
2991+ LW_SAFE_FREE_STRING(pszEsc);
2992+
2993+ pszStr += strlen(pszStr) + 1;
2994+ }
2995+ fprintf(stdout, "\n");
2996+ }
2997+
2998+cleanup:
2999+
3000+ LW_SAFE_FREE_STRING(pszaArg);
3001+ LW_SAFE_FREE_STRING(pszEsc);
3002+
3003+ return dwError;
3004+
3005+error:
3006+ goto cleanup;
3007+}
3008+
3009+DWORD
3010+CapabilityShow(
3011+ PCAPABILITY pCapability,
3012+ BOOL bConcise
3013+ )
3014+{
3015+ DWORD dwError = 0;
3016+ PREGISTRY pRegistry = NULL;
3017+ DWORD dwValue = 0;
3018+ PSTR pszaArg = NULL;
3019+ PSTR pszEsc = NULL;
3020+ BOOLEAN bRegistryValueFound = FALSE;
3021+ BOOLEAN bLocalPolicy = FALSE;
3022+
3023+ if (!pCapability)
3024+ {
3025+ dwError = ERROR_INVALID_PARAMETER;
3026+ BAIL_ON_ERROR(dwError);
3027+ }
3028+
3029+ if (!pCapability->pRegistry)
3030+ {
3031+ goto cleanup;
3032+ }
3033+
3034+ pRegistry = pCapability->pRegistry;
3035+
3036+ dwError = CapabilityGetRegistry(pRegistry, &pszaArg, &dwValue, &bLocalPolicy);
3037+ if (dwError == 0)
3038+ {
3039+ bRegistryValueFound = TRUE;
3040+ }
3041+ else if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
3042+ {
3043+ dwError = 0;
3044+ bRegistryValueFound = FALSE;
3045+ }
3046+ BAIL_ON_ERROR(dwError);
3047+
3048+ if (bConcise)
3049+ {
3050+ if (!bRegistryValueFound)
3051+ {
3052+ fprintf(stdout, "missing\n%s\n", pRegistry->pszType);
3053+ }
3054+ else if (!strcmp(pRegistry->pszType, "boolean"))
3055+ {
3056+ fprintf(stdout, "boolean\n%s\n", dwValue ? "true" : "false");
3057+ }
3058+ else if (!strcmp(pRegistry->pszType, "dword"))
3059+ {
3060+ fprintf(stdout, "dword\n%lu\n", (unsigned long) dwValue);
3061+ }
3062+ else if (!strcmp(pRegistry->pszType, "string"))
3063+ {
3064+ fprintf(stdout, "string\n%s\n", pszaArg);
3065+ }
3066+ else if (!strcmp(pRegistry->pszType, "multistring"))
3067+ {
3068+ fprintf(stdout, "multistring\n");
3069+ PCSTR pszStr = pszaArg;
3070+ while (*pszStr)
3071+ {
3072+ fprintf(stdout, "%s\n", pszStr);
3073+ pszStr += strlen(pszStr) + 1;
3074+ }
3075+ fprintf(stdout, "\n");
3076+ }
3077+
3078+ if (bRegistryValueFound)
3079+ {
3080+ if (bLocalPolicy)
3081+ {
3082+ fprintf(stdout, "local policy\n");
3083+ }
3084+ else
3085+ {
3086+ fprintf(stdout, "group policy\n");
3087+ }
3088+ }
3089+ else
3090+ {
3091+ fprintf(stdout, "no policy\n");
3092+ }
3093+ }
3094+ else
3095+ {
3096+ fprintf(stdout, "Name: %s\n", pCapability->pszName);
3097+ fprintf(stdout, "Description: %s\n",
3098+ pCapability->pszDescription ? pCapability->pszDescription : "");
3099+ if (!bRegistryValueFound)
3100+ {
3101+ fprintf(stdout, "Type (Missing From Registry): %s\n",
3102+ pCapability->pRegistry->pszType);
3103+ }
3104+ else
3105+ {
3106+ fprintf(stdout, "Type: %s\n", pCapability->pRegistry->pszType);
3107+ if (!strcmp(pRegistry->pszType, "boolean"))
3108+ {
3109+ fprintf(stdout, "Current Value: %s\n", dwValue ? "true" : "false");
3110+ fprintf(stdout, "Accepted Values: true, false\n");
3111+ }
3112+ else if (!strcmp(pRegistry->pszType, "dword"))
3113+ {
3114+ xmlNodePtr xmlAccept = NULL;
3115+ fprintf(stdout, "Current Value: %lu\n", (unsigned long) dwValue);
3116+
3117+ xmlAccept = FindNext(
3118+ pRegistry->pxRegistry->xmlChildrenNode,
3119+ "accept");
3120+ if (!xmlAccept)
3121+ {
3122+ fprintf(stdout, "Accepted Range: [0, 4294967295]\n");
3123+ }
3124+ while (xmlAccept)
3125+ {
3126+ xmlNodePtr xmlRange = NULL;
3127+
3128+ xmlRange = FindNext(xmlAccept->xmlChildrenNode, "range");
3129+ while(xmlRange)
3130+ {
3131+ xmlChar *xszMin = NULL;
3132+ xmlChar *xszMax = NULL;
3133+
3134+ xszMin = xmlGetProp(xmlRange, (const xmlChar*)"min");
3135+ xszMax = xmlGetProp(xmlRange, (const xmlChar*)"max");
3136+ if (xszMin && xszMax)
3137+ {
3138+ fprintf(stdout,
3139+ "Accepted Range: [%s, %s]\n",
3140+ xszMin,
3141+ xszMax);
3142+ }
3143+ if (xszMin)
3144+ {
3145+ xmlFree(xszMin);
3146+ xszMin = NULL;
3147+ }
3148+ if (xszMax)
3149+ {
3150+ xmlFree(xszMax);
3151+ xszMax = NULL;
3152+ }
3153+ xmlRange = FindNext(xmlRange->next, "range");
3154+ }
3155+ xmlAccept = FindNext(xmlAccept->next, "accept");
3156+ }
3157+ }
3158+ else if (!strcmp(pRegistry->pszType, "string"))
3159+ {
3160+ xmlNodePtr xmlAccept = NULL;
3161+
3162+ dwError = UtilAllocateEscapedString(pszaArg, &pszEsc);
3163+ BAIL_ON_ERROR(dwError);
3164+
3165+ fprintf(stdout, "Current Value: \"%s\"\n", pszEsc);
3166+
3167+ LW_SAFE_FREE_STRING(pszEsc);
3168+
3169+ xmlAccept = FindNext(
3170+ pRegistry->pxRegistry->xmlChildrenNode,
3171+ "accept");
3172+ while (xmlAccept)
3173+ {
3174+ xmlNodePtr xmlValue = NULL;
3175+
3176+ xmlValue = FindNext(xmlAccept->xmlChildrenNode, "value");
3177+ while(xmlValue)
3178+ {
3179+ xmlChar *xszValue = NULL;
3180+
3181+ xszValue = xmlNodeListGetString(
3182+ pCapability->xmlDoc,
3183+ xmlValue->xmlChildrenNode,
3184+ TRUE);
3185+ if (xszValue)
3186+ {
3187+ fprintf(stdout, "Acceptable Value: \"%s\"\n", (PSTR)xszValue);
3188+ xmlFree(xszValue);
3189+ xszValue = NULL;
3190+ }
3191+ xmlValue = FindNext(xmlValue->next, "value");
3192+ }
3193+ xmlAccept = FindNext(xmlAccept->next, "accept");
3194+ }
3195+ }
3196+ else if (!strcmp(pRegistry->pszType, "multistring"))
3197+ {
3198+ fprintf(stdout, "Current Values:\n");
3199+ PCSTR pszStr = pszaArg;
3200+ while (*pszStr)
3201+ {
3202+ dwError = UtilAllocateEscapedString(pszStr, &pszEsc);
3203+ BAIL_ON_ERROR(dwError);
3204+
3205+ fprintf(stdout, "\"%s\"\n", pszEsc);
3206+
3207+ LW_SAFE_FREE_STRING(pszEsc);
3208+
3209+ pszStr += strlen(pszStr) + 1;
3210+ }
3211+ }
3212+
3213+ if (bLocalPolicy)
3214+ fprintf(stdout, "Current Value is determined by local policy.\n");
3215+ else
3216+ fprintf(stdout, "Value is determined by group policy in Active Directory.\n");
3217+ }
3218+ }
3219+cleanup:
3220+
3221+ LW_SAFE_FREE_STRING(pszaArg);
3222+ LW_SAFE_FREE_STRING(pszEsc);
3223+
3224+ return dwError;
3225+
3226+error:
3227+ goto cleanup;
3228+}
3229+
3230+static
3231+xmlNodePtr
3232+FindNext(
3233+ xmlNodePtr pxChild,
3234+ PSTR pszChild)
3235+{
3236+ while (pxChild)
3237+ {
3238+ if (pxChild->type == XML_ELEMENT_NODE)
3239+ {
3240+ if (!xmlStrcmp(pxChild->name, (const xmlChar*)pszChild))
3241+ {
3242+ break;
3243+ }
3244+ }
3245+ pxChild = pxChild->next;
3246+ }
3247+ return pxChild;
3248+}
3249+
3250
3251=== added file 'lwconfig/src/capability.h'
3252--- lwconfig/src/capability.h 1970-01-01 00:00:00 +0000
3253+++ lwconfig/src/capability.h 2011-02-24 04:27:55 +0000
3254@@ -0,0 +1,72 @@
3255+/*
3256+ * Copyright (c) Likewise Software. All rights reserved.
3257+ *
3258+ * This program is free software; you can redistribute it and/or modify
3259+ * it under the terms of the GNU General Public License as published by
3260+ * the Free Software Foundation; either version 2 of the License, or (at
3261+ * your option) any later version.
3262+ *
3263+ * This program is distributed in the hope that it will be useful, but
3264+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3265+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3266+ * for more details. You should have received a copy of the GNU General
3267+ * Public License along with this program. If not, see
3268+ * <http://www.gnu.org/licenses/>.
3269+ *
3270+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
3271+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
3272+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
3273+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
3274+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
3275+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
3276+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
3277+ * license@likewise.com
3278+ */
3279+#ifndef LWCONFIG_CAPABILITY_H
3280+#define LWCONFIG_CAPABILITY_H
3281+
3282+DWORD
3283+CapabilityAllocate(
3284+ xmlDocPtr xmlDoc,
3285+ xmlNodePtr xmlNode,
3286+ PCAPABILITY *ppCapability
3287+ );
3288+
3289+void
3290+CapabilityFree(
3291+ PCAPABILITY pCapability
3292+ );
3293+
3294+DWORD
3295+CapabilityFindByName(
3296+ xmlDocPtr doc,
3297+ PCSTR name,
3298+ PCAPABILITY *ppCapability
3299+ );
3300+
3301+DWORD
3302+CapabilityEditRegistry(
3303+ PCAPABILITY pCapability,
3304+ PCSTR pszaArg,
3305+ BOOLEAN pVerbose
3306+ );
3307+
3308+DWORD
3309+CapabilityApply(
3310+ PCAPABILITY pCapability,
3311+ BOOLEAN bVerbose
3312+ );
3313+
3314+DWORD
3315+CapabilityDump(
3316+ PCAPABILITY pCapability
3317+ );
3318+
3319+DWORD
3320+CapabilityShow(
3321+ PCAPABILITY pCapability,
3322+ BOOL bConcise
3323+ );
3324+
3325+#endif
3326+
3327
3328=== added file 'lwconfig/src/defs.h'
3329--- lwconfig/src/defs.h 1970-01-01 00:00:00 +0000
3330+++ lwconfig/src/defs.h 2011-02-24 04:27:55 +0000
3331@@ -0,0 +1,49 @@
3332+/*
3333+ * Copyright (c) Likewise Software. All rights reserved.
3334+ *
3335+ * This program is free software; you can redistribute it and/or modify
3336+ * it under the terms of the GNU General Public License as published by
3337+ * the Free Software Foundation; either version 2 of the License, or (at
3338+ * your option) any later version.
3339+ *
3340+ * This program is distributed in the hope that it will be useful, but
3341+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3342+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3343+ * for more details. You should have received a copy of the GNU General
3344+ * Public License along with this program. If not, see
3345+ * <http://www.gnu.org/licenses/>.
3346+ *
3347+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
3348+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
3349+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
3350+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
3351+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
3352+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
3353+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
3354+ * license@likewise.com
3355+ */
3356+#ifndef DEFS_H
3357+#define DEFS_H
3358+
3359+#define BAIL_ON_ERROR(x) if (x) goto error
3360+
3361+#define APP_ERROR_BAD_XML 0x20000000
3362+#define APP_ERROR_XML_DUPLICATED_ELEMENT 0x20000001
3363+#define APP_ERROR_XML_MISSING_ELEMENT 0x20000002
3364+#define APP_ERROR_XPATH_EVAL_FAILED 0x20000003
3365+#define APP_ERROR_CAPABILITY_NOT_FOUND 0x20000004
3366+#define APP_ERROR_INVALID_DWORD 0x20000005
3367+#define APP_ERROR_INVALID_BOOLEAN 0x20000006
3368+#define APP_ERROR_UNKNOWN_TYPE 0x20000007
3369+#define APP_ERROR_INVALID_SUFFIX 0x20000008
3370+#define APP_ERROR_PARAMETER_REQUIRED 0x20000009
3371+#define APP_ERROR_UNEXPECTED_VALUE 0x2000000a
3372+#define APP_ERROR_COULD_NOT_FORK 0x2000000b
3373+#define APP_ERROR_INVALID_ESCAPE_SEQUENCE 0x2000000c
3374+#define APP_ERROR_UNTERMINATED_QUOTE 0x2000000d
3375+#define APP_ERROR_BAD_REGISTRY_PATH 0x2000000e
3376+#define APP_ERROR_VALUE_NOT_ACCEPTED 0x2000000f
3377+#define APP_ERROR_PROGRAM_ERROR 0x20000010
3378+#define APP_ERROR_CAPABILITY_MULTIPLE_MATCHES 0x20000011
3379+#define APP_ERROR_XML_MISSING_ATTRIBUTE 0x20000012
3380+#endif
3381
3382=== added file 'lwconfig/src/includes.h'
3383--- lwconfig/src/includes.h 1970-01-01 00:00:00 +0000
3384+++ lwconfig/src/includes.h 2011-02-24 04:27:55 +0000
3385@@ -0,0 +1,53 @@
3386+/*
3387+ * Copyright (c) Likewise Software. All rights reserved.
3388+ *
3389+ * This program is free software; you can redistribute it and/or modify
3390+ * it under the terms of the GNU General Public License as published by
3391+ * the Free Software Foundation; either version 2 of the License, or (at
3392+ * your option) any later version.
3393+ *
3394+ * This program is distributed in the hope that it will be useful, but
3395+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3396+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3397+ * for more details. You should have received a copy of the GNU General
3398+ * Public License along with this program. If not, see
3399+ * <http://www.gnu.org/licenses/>.
3400+ *
3401+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
3402+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
3403+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
3404+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
3405+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
3406+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
3407+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
3408+ * license@likewise.com
3409+ */
3410+#include "config.h"
3411+
3412+#include <stdlib.h>
3413+#include <stdio.h>
3414+#include <string.h>
3415+#include <assert.h>
3416+#include <unistd.h>
3417+#include <errno.h>
3418+#include <sys/types.h>
3419+#include <regex.h>
3420+#include <locale.h>
3421+
3422+#include <libxml/tree.h>
3423+#include <libxml/parser.h>
3424+#include <libxml/xpath.h>
3425+#include <libxml/xpathInternals.h>
3426+
3427+#include <reg/lwreg.h>
3428+#include <reg/regutil.h>
3429+
3430+#include <lwstr.h>
3431+#include <lwmem.h>
3432+#include <lwerror.h>
3433+
3434+#include "defs.h"
3435+#include "structs.h"
3436+#include "util.h"
3437+#include "capability.h"
3438+
3439
3440=== added file 'lwconfig/src/main.c'
3441--- lwconfig/src/main.c 1970-01-01 00:00:00 +0000
3442+++ lwconfig/src/main.c 2011-02-24 04:27:55 +0000
3443@@ -0,0 +1,545 @@
3444+/*
3445+ * Copyright (c) Likewise Software. All rights reserved.
3446+ *
3447+ * This program is free software; you can redistribute it and/or modify
3448+ * it under the terms of the GNU General Public License as published by
3449+ * the Free Software Foundation; either version 2 of the License, or (at
3450+ * your option) any later version.
3451+ *
3452+ * This program is distributed in the hope that it will be useful, but
3453+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3454+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3455+ * for more details. You should have received a copy of the GNU General
3456+ * Public License along with this program. If not, see
3457+ * <http://www.gnu.org/licenses/>.
3458+ *
3459+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
3460+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
3461+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
3462+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
3463+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
3464+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
3465+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
3466+ * license@likewise.com
3467+ */
3468+
3469+#include "includes.h"
3470+
3471+DWORD
3472+SetOperation(
3473+ xmlDocPtr doc,
3474+ PCSTR pszName,
3475+ PCSTR pszaArg,
3476+ BOOLEAN bVerbose
3477+ );
3478+
3479+DWORD
3480+ShowOperation(
3481+ xmlDocPtr doc,
3482+ PCSTR pszName,
3483+ BOOLEAN bConcise
3484+ );
3485+
3486+static
3487+void
3488+PrintUsage()
3489+{
3490+ fputs(
3491+"Usage: lwconfig [OPTIONS] [COMMAND]\n"
3492+"Modify or view the configuration.\n"
3493+"\n"
3494+" Options:\n"
3495+" --verbose Display additional information.\n"
3496+"\n"
3497+" Commands:\n"
3498+" SETTING [VALUE] Change SETTING to the given VALUE(s) or the\n"
3499+" default value if no value is specified.\n"
3500+" --list Display names of all settings.\n"
3501+" --show SETTING Display current value(s) of SETTING.\n"
3502+" --detail SETTING Display current value(s) and details of SETTING.\n"
3503+" --file FILE Read FILE with each line beginning with a\n"
3504+" setting name followed by value(s). Use '.'\n"
3505+" for reading from stdin.\n"
3506+" --dump Dump all settings in a format suitable for use\n"
3507+" with --file.\n"
3508+ ,stderr);
3509+}
3510+
3511+DWORD
3512+ListCapabilities(
3513+ xmlDocPtr doc
3514+ )
3515+{
3516+ DWORD dwError = 0;
3517+ xmlXPathContextPtr xpathCtx = NULL;
3518+ xmlXPathObjectPtr xpathObj = NULL;
3519+ xmlNodeSetPtr nodes = NULL;
3520+ size_t i;
3521+
3522+ xpathCtx = xmlXPathNewContext(doc);
3523+ if (!xpathCtx)
3524+ {
3525+ dwError = ERROR_OUTOFMEMORY;
3526+ BAIL_ON_ERROR(dwError);
3527+ }
3528+
3529+ xpathObj = xmlXPathEvalExpression(
3530+ (const xmlChar*)"/capabilities/section",
3531+ xpathCtx);
3532+ if (!xpathObj)
3533+ {
3534+ dwError = APP_ERROR_XPATH_EVAL_FAILED;
3535+ BAIL_ON_ERROR(dwError);
3536+ }
3537+
3538+ nodes = xpathObj->nodesetval;
3539+ for (i = 0; i < nodes->nodeNr; i++)
3540+ {
3541+ if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE)
3542+ {
3543+ xmlNodePtr cur = nodes->nodeTab[i];
3544+ xmlNodePtr child = NULL;
3545+ xmlChar *section = NULL;
3546+
3547+ section = xmlGetProp(cur, (const xmlChar*) "section");
3548+ if (section)
3549+ fprintf(stdout, "[%s]\n", section);
3550+ else
3551+ fprintf(stdout, "\n");
3552+ xmlFree(section);
3553+ section = NULL;
3554+
3555+ for (child = cur->xmlChildrenNode; child; child = child->next)
3556+ {
3557+ PCAPABILITY cap = NULL;
3558+ if (child->type != XML_ELEMENT_NODE)
3559+ continue;
3560+ if (xmlStrcmp(child->name, (const xmlChar*)"capability"))
3561+ continue;
3562+
3563+ dwError = CapabilityAllocate(doc, child, &cap);
3564+ BAIL_ON_ERROR(dwError);
3565+
3566+ if (cap->pszName)
3567+ fprintf(stdout, "\t%s\n", cap->pszName);
3568+
3569+ CapabilityFree(cap);
3570+ cap = NULL;
3571+ }
3572+ }
3573+ }
3574+
3575+cleanup:
3576+ xmlXPathFreeObject(xpathObj);
3577+ xmlXPathFreeContext(xpathCtx);
3578+ return dwError;
3579+
3580+error:
3581+ goto cleanup;
3582+}
3583+
3584+DWORD
3585+SetOperation(
3586+ xmlDocPtr doc,
3587+ PCSTR pszName,
3588+ PCSTR pszaArg,
3589+ BOOLEAN bVerbose
3590+ )
3591+{
3592+ DWORD dwError = 0;
3593+ PCAPABILITY pCapability = NULL;
3594+
3595+ dwError = CapabilityFindByName(doc, pszName, &pCapability);
3596+ BAIL_ON_ERROR(dwError);
3597+
3598+ dwError = CapabilityEditRegistry(pCapability, pszaArg, bVerbose);
3599+ BAIL_ON_ERROR(dwError);
3600+
3601+ dwError = CapabilityApply(pCapability, bVerbose);
3602+ BAIL_ON_ERROR(dwError);
3603+
3604+cleanup:
3605+ CapabilityFree(pCapability);
3606+ return dwError;
3607+
3608+error:
3609+ goto cleanup;
3610+}
3611+
3612+DWORD
3613+ShowOperation(
3614+ xmlDocPtr doc,
3615+ PCSTR pszName,
3616+ BOOLEAN bConcise
3617+ )
3618+{
3619+ DWORD dwError = 0;
3620+ PCAPABILITY pCapability = NULL;
3621+
3622+ dwError = CapabilityFindByName(doc, pszName, &pCapability);
3623+ BAIL_ON_ERROR(dwError);
3624+
3625+ dwError = CapabilityShow(pCapability, bConcise);
3626+ BAIL_ON_ERROR(dwError);
3627+
3628+cleanup:
3629+ CapabilityFree(pCapability);
3630+ return dwError;
3631+
3632+error:
3633+ goto cleanup;
3634+}
3635+
3636+DWORD
3637+DumpOperation(
3638+ xmlDocPtr doc,
3639+ BOOLEAN bPolicyOnly
3640+ )
3641+{
3642+ DWORD dwError = 0;
3643+ PCAPABILITY pCapability = NULL;
3644+ xmlXPathContextPtr xpathCtx = NULL;
3645+ xmlXPathObjectPtr xpathObj = NULL;
3646+ xmlNodeSetPtr nodes = NULL;
3647+ size_t i;
3648+
3649+ xpathCtx = xmlXPathNewContext(doc);
3650+ if (!xpathCtx)
3651+ {
3652+ dwError = ERROR_OUTOFMEMORY;
3653+ BAIL_ON_ERROR(dwError);
3654+ }
3655+
3656+ xpathObj = xmlXPathEvalExpression(
3657+ (const xmlChar*)"/capabilities/section/capability",
3658+ xpathCtx);
3659+ if (!xpathObj)
3660+ {
3661+ dwError = APP_ERROR_XPATH_EVAL_FAILED;
3662+ BAIL_ON_ERROR(dwError);
3663+ }
3664+
3665+ nodes = xpathObj->nodesetval;
3666+ for (i = 0; i < nodes->nodeNr; i++)
3667+ {
3668+ if (nodes->nodeTab[i]->type != XML_ELEMENT_NODE)
3669+ continue;
3670+
3671+ if (xmlStrcmp(nodes->nodeTab[i]->name, (const xmlChar*)"capability"))
3672+ continue;
3673+
3674+ dwError = CapabilityAllocate(doc, nodes->nodeTab[i], &pCapability);
3675+ BAIL_ON_ERROR(dwError);
3676+
3677+ dwError = CapabilityDump(pCapability);
3678+ BAIL_ON_ERROR(dwError);
3679+
3680+ CapabilityFree(pCapability);
3681+ pCapability = NULL;
3682+ }
3683+
3684+cleanup:
3685+ CapabilityFree(pCapability);
3686+ pCapability = NULL;
3687+ xmlXPathFreeObject(xpathObj);
3688+ xmlXPathFreeContext(xpathCtx);
3689+ return dwError;
3690+
3691+error:
3692+ goto cleanup;
3693+}
3694+
3695+int main(int argc, const char *argv[])
3696+{
3697+ DWORD dwError = 0;
3698+ BOOLEAN bListCapabilities = FALSE;
3699+ BOOLEAN bFile = FALSE;
3700+ PCSTR pszFile = NULL;
3701+ BOOLEAN bShowCapability = FALSE;
3702+ BOOLEAN bDumpCapability = FALSE;
3703+ BOOLEAN bDetailCapability = FALSE;
3704+ BOOLEAN bVerbose = FALSE;
3705+ PCSTR pszCapability = NULL;
3706+ FILE *fpFile = NULL;
3707+ PSTR pszLine = NULL;
3708+ PSTR *ppszArgs = NULL;
3709+ DWORD dwArgs = 0;
3710+ PSTR pszaArg = NULL;
3711+ xmlDocPtr doc = NULL;
3712+ int dwArgc = 1;
3713+ int returnErrorCode = 1;
3714+ size_t i;
3715+
3716+ setlocale(LC_ALL, "");
3717+
3718+ xmlInitParser();
3719+
3720+ doc = xmlParseFile(LWCONFIG_XML);
3721+ if (!doc)
3722+ {
3723+ dwError = APP_ERROR_BAD_XML;
3724+ BAIL_ON_ERROR(dwError);
3725+ }
3726+
3727+ if (argc == 1)
3728+ {
3729+ PrintUsage();
3730+ goto cleanup;
3731+ }
3732+
3733+ for (dwArgc = 1; dwArgc < argc; dwArgc++)
3734+ {
3735+ if (!strcmp(argv[dwArgc], "--help"))
3736+ {
3737+ PrintUsage();
3738+ goto cleanup;
3739+ }
3740+ else if (!strcmp(argv[dwArgc], "--file"))
3741+ {
3742+ if (argc == dwArgc+1)
3743+ {
3744+ PrintUsage();
3745+ goto cleanup;
3746+ }
3747+
3748+ bFile = TRUE;
3749+ pszFile = argv[++dwArgc];
3750+ }
3751+ else if (!strcmp(argv[dwArgc], "--list"))
3752+ {
3753+ bListCapabilities = TRUE;
3754+ }
3755+ else if (!strcmp(argv[dwArgc], "--dump"))
3756+ {
3757+ bDumpCapability = TRUE;
3758+ }
3759+ else if (!strcmp(argv[dwArgc], "--show"))
3760+ {
3761+ if (argc == dwArgc+1)
3762+ {
3763+ PrintUsage();
3764+ goto cleanup;
3765+ }
3766+
3767+ bShowCapability = TRUE;
3768+ pszCapability = argv[++dwArgc];
3769+ }
3770+ else if (!strcmp(argv[dwArgc], "--detail") ||
3771+ !strcmp(argv[dwArgc], "--details"))
3772+ {
3773+ if (argc == dwArgc+1)
3774+ {
3775+ PrintUsage();
3776+ goto cleanup;
3777+ }
3778+ bDetailCapability = TRUE;
3779+ pszCapability = argv[++dwArgc];
3780+ }
3781+ else if (!strcmp(argv[dwArgc], "--verbose"))
3782+ {
3783+ bVerbose = TRUE;
3784+ }
3785+ else if (!strncmp(argv[dwArgc], "--", 2))
3786+ {
3787+ PrintUsage();
3788+ goto cleanup;
3789+ }
3790+ else
3791+ break;
3792+ }
3793+
3794+ if (bListCapabilities)
3795+ {
3796+ dwError = ListCapabilities(doc);
3797+ BAIL_ON_ERROR(dwError);
3798+ }
3799+ else if (bDumpCapability)
3800+ {
3801+ dwError = DumpOperation(doc, TRUE);
3802+ BAIL_ON_ERROR(dwError);
3803+ }
3804+ else if (bFile)
3805+ {
3806+ if (!strcmp(pszFile, "."))
3807+ fpFile = stdin;
3808+ else if ((fpFile = fopen(pszFile, "r")) == NULL)
3809+ {
3810+ dwError = LwMapErrnoToLwError(errno);
3811+ BAIL_ON_ERROR(dwError);
3812+ }
3813+
3814+ while ((dwError = UtilReadLine(fpFile, &pszLine)) == 0)
3815+ {
3816+ dwError = UtilParseLine(pszLine, &ppszArgs, &dwArgs);
3817+ BAIL_ON_ERROR(dwError);
3818+
3819+ if (dwArgs > 0)
3820+ {
3821+ dwError = UtilAllocateMultistring((PCSTR*)ppszArgs + 1, dwArgs -
3822+ 1, &pszaArg);
3823+ BAIL_ON_ERROR(dwError);
3824+
3825+ dwError = SetOperation(doc, ppszArgs[0], pszaArg, bVerbose);
3826+ BAIL_ON_ERROR(dwError);
3827+
3828+ for (i = 0; i < dwArgs; i++)
3829+ LW_SAFE_FREE_MEMORY(ppszArgs[i]);
3830+ dwArgs = 0;
3831+ LW_SAFE_FREE_MEMORY(ppszArgs);
3832+ LW_SAFE_FREE_MEMORY(pszaArg);
3833+ }
3834+
3835+ LW_SAFE_FREE_STRING(pszLine);
3836+ }
3837+ if (dwError == ERROR_HANDLE_EOF)
3838+ {
3839+ dwError = 0;
3840+ }
3841+ BAIL_ON_ERROR(dwError);
3842+ }
3843+ else if (bShowCapability || bDetailCapability)
3844+ {
3845+ dwError = ShowOperation(doc, pszCapability, bShowCapability);
3846+ BAIL_ON_ERROR(dwError);
3847+ }
3848+ else
3849+ {
3850+ if (argc - dwArgc > 0)
3851+ {
3852+ if (argc - dwArgc > 1)
3853+ {
3854+ dwError = UtilAllocateMultistring((PCSTR*)argv + dwArgc + 1,
3855+ argc - dwArgc - 1, &pszaArg);
3856+ BAIL_ON_ERROR(dwError);
3857+ }
3858+
3859+ dwError = SetOperation(doc, argv[dwArgc], pszaArg, bVerbose);
3860+ BAIL_ON_ERROR(dwError);
3861+ }
3862+ else
3863+ {
3864+ PrintUsage();
3865+ goto cleanup;
3866+ }
3867+ }
3868+
3869+cleanup:
3870+
3871+ LW_SAFE_FREE_MEMORY(pszaArg);
3872+
3873+ for (i = 0; i < dwArgs; i++)
3874+ LW_SAFE_FREE_MEMORY(ppszArgs[i]);
3875+ dwArgs = 0;
3876+ LW_SAFE_FREE_MEMORY(ppszArgs);
3877+
3878+ if (fpFile && fpFile != stdin)
3879+ {
3880+ fclose(fpFile);
3881+ fpFile = NULL;
3882+ }
3883+ xmlFreeDoc(doc);
3884+ doc = NULL;
3885+
3886+ xmlCleanupParser();
3887+ if (dwError)
3888+ {
3889+ size_t size = 0;
3890+ char buf[1024];
3891+
3892+ buf[0] = '\0';
3893+
3894+ if (_LW_ERROR_REG_BASE <= dwError && dwError <= _LW_ERROR_REG_MAX)
3895+ {
3896+ size = LwRegGetErrorString(dwError, buf, sizeof(buf));
3897+ if (size > sizeof(buf))
3898+ buf[0] = '\0';
3899+ }
3900+ else if (dwError >= 0x20000000)
3901+ {
3902+ switch(dwError)
3903+ {
3904+ case APP_ERROR_XML_DUPLICATED_ELEMENT:
3905+ strcpy(buf, "Duplicated XML element");
3906+ break;
3907+ case APP_ERROR_XML_MISSING_ELEMENT:
3908+ strcpy(buf, "Missing XML element");
3909+ break;
3910+ case APP_ERROR_XPATH_EVAL_FAILED:
3911+ strcpy(buf, "Could not evaluate XPath expression");
3912+ break;
3913+ case APP_ERROR_CAPABILITY_NOT_FOUND:
3914+ strcpy(buf, "Capability not found");
3915+ returnErrorCode = 2;
3916+ break;
3917+ case APP_ERROR_INVALID_DWORD:
3918+ strcpy(buf, "Could not interpret value as dword");
3919+ returnErrorCode = 3;
3920+ break;
3921+ case APP_ERROR_INVALID_BOOLEAN:
3922+ strcpy(buf, "Could not interpret value as boolean");
3923+ returnErrorCode = 3;
3924+ break;
3925+ case APP_ERROR_INVALID_SUFFIX:
3926+ strcpy(buf, "Suffix on DWORD does not match known units");
3927+ returnErrorCode = 3;
3928+ break;
3929+ case APP_ERROR_PARAMETER_REQUIRED:
3930+ strcpy(buf, "Argument required -- no default is present");
3931+ returnErrorCode = 4;
3932+ break;
3933+ case APP_ERROR_UNEXPECTED_VALUE:
3934+ strcpy(buf, "Bad value in /var/lib/likewise/lwconfig.xml");
3935+ break;
3936+ case APP_ERROR_COULD_NOT_FORK:
3937+ strcpy(buf, "Could not fork");
3938+ break;
3939+ case APP_ERROR_BAD_XML:
3940+ strcpy(buf, "Malformed XML in /var/lib/likewise/lwconfig.xml");
3941+ break;
3942+ case APP_ERROR_INVALID_ESCAPE_SEQUENCE:
3943+ strcpy(buf, "Bad escape sequence");
3944+ returnErrorCode = 3;
3945+ break;
3946+ case APP_ERROR_UNTERMINATED_QUOTE:
3947+ strcpy(buf, "Unterminated quote");
3948+ returnErrorCode = 3;
3949+ break;
3950+ case APP_ERROR_VALUE_NOT_ACCEPTED:
3951+ strcpy(buf, "Value not in accepted range");
3952+ returnErrorCode = 3;
3953+ break;
3954+ case APP_ERROR_PROGRAM_ERROR:
3955+ strcpy(buf, "Error returned by external program");
3956+ returnErrorCode = 5;
3957+ break;
3958+ case APP_ERROR_CAPABILITY_MULTIPLE_MATCHES:
3959+ strcpy(buf, "Multiple capabilties matched; aborting.");
3960+ returnErrorCode = 6;
3961+ break;
3962+ case APP_ERROR_XML_MISSING_ATTRIBUTE:
3963+ strcpy(buf, "Missing XML attribute");
3964+ break;
3965+ }
3966+ }
3967+ if (buf[0] == '\0')
3968+ {
3969+ size = LwGetErrorString(dwError, buf, sizeof(buf));
3970+ if (size > sizeof(buf))
3971+ buf[0] = '\0';
3972+ }
3973+
3974+ if (buf[0])
3975+ {
3976+ fprintf(stderr, "Error: %s\n", buf);
3977+ }
3978+ else
3979+ {
3980+ fprintf(stderr, "Error: %lu\n", (unsigned long) dwError);
3981+ }
3982+ return returnErrorCode;
3983+ }
3984+ return 0;
3985+
3986+error:
3987+ goto cleanup;
3988+}
3989
3990=== added file 'lwconfig/src/structs.h'
3991--- lwconfig/src/structs.h 1970-01-01 00:00:00 +0000
3992+++ lwconfig/src/structs.h 2011-02-24 04:27:55 +0000
3993@@ -0,0 +1,48 @@
3994+/*
3995+ * Copyright (c) Likewise Software. All rights reserved.
3996+ *
3997+ * This program is free software; you can redistribute it and/or modify
3998+ * it under the terms of the GNU General Public License as published by
3999+ * the Free Software Foundation; either version 2 of the License, or (at
4000+ * your option) any later version.
4001+ *
4002+ * This program is distributed in the hope that it will be useful, but
4003+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4004+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4005+ * for more details. You should have received a copy of the GNU General
4006+ * Public License along with this program. If not, see
4007+ * <http://www.gnu.org/licenses/>.
4008+ *
4009+ * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
4010+ * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
4011+ * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
4012+ * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
4013+ * GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
4014+ * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
4015+ * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
4016+ * license@likewise.com
4017+ */
4018+
4019+#ifndef LWCONFIG_STRUCTS_H
4020+#define LWCONFIG_STRUCTS_H
4021+
4022+typedef struct _REGISTRY
4023+{
4024+ xmlNodePtr pxRegistry;
4025+ PSTR pszLocalPath;
4026+ PSTR pszPolicyPath;
4027+ PSTR pszType;
4028+ PSTR pszDescription;
4029+ PSTR pszaDefault;
4030+} REGISTRY, *PREGISTRY;
4031+
4032+typedef struct _CAPABILITY
4033+{
4034+ xmlDocPtr xmlDoc;
4035+ xmlNodePtr xmlNodeCapability;
4036+ PSTR pszName;
4037+ PSTR pszDescription;
4038+ PREGISTRY pRegistry;
4039+} CAPABILITY, *PCAPABILITY;
4040+
4041+#endif
4042
4043=== added file 'lwconfig/src/util.c'
4044--- lwconfig/src/util.c 1970-01-01 00:00:00 +0000
4045+++ lwconfig/src/util.c 2011-02-24 04:27:55 +0000
4046@@ -0,0 +1,660 @@
4047+/*
4048+* Copyright (c) Likewise Software. All rights reserved.
4049+*
4050+* This program is free software; you can redistribute it and/or modify
4051+* it under the terms of the GNU General Public License as published by
4052+* the Free Software Foundation; either version 2 of the License, or (at
4053+* your option) any later version.
4054+*
4055+* This program is distributed in the hope that it will be useful, but
4056+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4057+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4058+* for more details. You should have received a copy of the GNU General
4059+* Public License along with this program. If not, see
4060+* <http://www.gnu.org/licenses/>.
4061+*
4062+* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
4063+* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
4064+* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
4065+* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
4066+* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
4067+* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
4068+* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
4069+* license@likewise.com
4070+*/
4071+
4072+#include "includes.h"
4073+
4074+DWORD
4075+UtilAllocateMultistring(
4076+ PCSTR *ppszValues,
4077+ DWORD dwValues,
4078+ PSTR *ppszValue
4079+ )
4080+{
4081+ DWORD dwError = 0;
4082+ DWORD dwLength = 0;
4083+ PSTR pszValue = NULL;
4084+ size_t i;
4085+
4086+ if (dwValues)
4087+ {
4088+ for (i = 0; i < dwValues; i++)
4089+ {
4090+ dwLength += strlen(ppszValues[i]) + 1;
4091+ }
4092+ dwLength++;
4093+
4094+
4095+ dwError = LwAllocateMemory(dwLength, (PVOID*)&pszValue);
4096+ BAIL_ON_ERROR(dwError);
4097+
4098+ dwLength = 0;
4099+ for (i = 0; i < dwValues; i++)
4100+ {
4101+ strcpy(pszValue + dwLength, ppszValues[i]);
4102+ dwLength += strlen(ppszValues[i]) + 1;
4103+ }
4104+ pszValue[dwLength++] = '\0';
4105+ }
4106+
4107+ *ppszValue = pszValue;
4108+
4109+cleanup:
4110+ return dwError;
4111+
4112+error:
4113+ LW_SAFE_FREE_MEMORY(pszValue);
4114+ goto cleanup;
4115+}
4116+
4117+DWORD
4118+UtilMultistringLength(
4119+ PCSTR pszValue
4120+ )
4121+{
4122+ PCSTR pszEnd = NULL;
4123+
4124+ pszEnd = pszValue;
4125+ while (*pszEnd)
4126+ {
4127+ pszEnd = pszEnd + strlen(pszEnd) + 1;
4128+ }
4129+
4130+ return (pszEnd - pszValue) + 1;
4131+}
4132+
4133+DWORD
4134+UtilDuplicateMultistring(
4135+ PCSTR pszValue,
4136+ PSTR *ppszValue
4137+ )
4138+{
4139+ DWORD dwError = 0;
4140+ DWORD dwLength = 0;
4141+ PSTR pszOut = NULL;
4142+
4143+ dwLength = UtilMultistringLength(pszValue);
4144+
4145+ dwError = LwAllocateMemory(dwLength, (PVOID*)&pszOut);
4146+ BAIL_ON_ERROR(dwError);
4147+
4148+ memcpy(pszOut, pszValue, dwLength);
4149+
4150+ *ppszValue = pszOut;
4151+
4152+cleanup:
4153+ return dwError;
4154+
4155+error:
4156+ LW_SAFE_FREE_MEMORY(pszOut);
4157+ goto cleanup;
4158+}
4159+
4160+DWORD
4161+UtilParseRegName(
4162+ PCSTR pszPath,
4163+ PSTR *ppszRoot,
4164+ PSTR *ppszKey,
4165+ PSTR *ppszName
4166+ )
4167+{
4168+ DWORD dwError = 0;
4169+ PSTR pszRoot = NULL;
4170+ PSTR pszKey = NULL;
4171+ PSTR pszName = NULL;
4172+ PCSTR pszFirst = NULL;
4173+ PCSTR pszLast = NULL;
4174+ PCSTR pszEnd = NULL;
4175+
4176+ if (!pszPath)
4177+ {
4178+ dwError = APP_ERROR_BAD_REGISTRY_PATH;
4179+ BAIL_ON_ERROR(dwError);
4180+ }
4181+
4182+ // Skip past a leading /
4183+ if (pszPath[0] == '\\')
4184+ pszPath++;
4185+
4186+ // Find the end of the string (before the terminator).
4187+ pszEnd = pszPath + strlen(pszPath) - 1;
4188+
4189+ pszFirst = strchr(pszPath, '\\');
4190+ if (!pszFirst)
4191+ {
4192+ dwError = APP_ERROR_BAD_REGISTRY_PATH;
4193+ BAIL_ON_ERROR(dwError);
4194+ }
4195+
4196+ pszLast = strrchr(pszPath, '\\');
4197+
4198+ dwError = LwAllocateMemory(pszFirst - pszPath + 1, (PVOID*) &pszRoot);
4199+ BAIL_ON_ERROR(dwError);
4200+
4201+ memcpy(pszRoot, pszPath, pszFirst - pszPath);
4202+ pszRoot[pszFirst - pszPath] = '\0';
4203+
4204+ if (pszFirst != pszLast)
4205+ {
4206+ dwError = LwAllocateMemory(pszLast - pszFirst + 1, (PVOID*) &pszKey);
4207+ BAIL_ON_ERROR(dwError);
4208+
4209+ memcpy(pszKey, pszFirst + 1, (pszLast - pszFirst) - 1);
4210+ pszKey[pszLast - pszFirst] = '\0';
4211+ }
4212+
4213+ dwError = LwAllocateMemory(pszEnd - pszLast + 1, (PVOID*) &pszName);
4214+ BAIL_ON_ERROR(dwError);
4215+
4216+ memcpy(pszName, pszLast + 1, pszEnd - pszLast);
4217+ pszName[pszEnd - pszLast] = '\0';
4218+
4219+ *ppszRoot = pszRoot;
4220+ *ppszKey = pszKey;
4221+ *ppszName = pszName;
4222+
4223+cleanup:
4224+ return dwError;
4225+
4226+error:
4227+ LW_SAFE_FREE_STRING(pszRoot);
4228+ LW_SAFE_FREE_STRING(pszKey);
4229+ LW_SAFE_FREE_STRING(pszName);
4230+ goto cleanup;
4231+}
4232+
4233+DWORD
4234+UtilSetValueExA(
4235+ PCSTR pszRoot,
4236+ PCSTR pszKey,
4237+ PCSTR pszValueName,
4238+ DWORD dwType,
4239+ const BYTE *pData,
4240+ DWORD cbData
4241+ )
4242+{
4243+ DWORD dwError = 0;
4244+ HANDLE hReg = NULL;
4245+ HKEY hRootKey = NULL;
4246+ HKEY hKeyKey = NULL;
4247+
4248+ dwError = LwRegOpenServer(&hReg);
4249+ BAIL_ON_ERROR(dwError);
4250+
4251+ if (!strcmp(pszRoot, "HKEY_THIS_MACHINE"))
4252+ {
4253+ dwError = LwRegOpenKeyExA(hReg, NULL, HKEY_THIS_MACHINE, 0, KEY_WRITE, &hRootKey);
4254+ BAIL_ON_ERROR(dwError);
4255+ }
4256+ else
4257+ {
4258+ dwError = LW_ERROR_INVALID_PARAMETER;
4259+ BAIL_ON_ERROR(dwError);
4260+ }
4261+
4262+ if (pszKey && pszKey[0])
4263+ {
4264+ dwError = LwRegOpenKeyExA(hReg, hRootKey, pszKey, 0, KEY_WRITE,
4265+ &hKeyKey);
4266+ BAIL_ON_ERROR(dwError);
4267+ }
4268+ else
4269+ {
4270+ hKeyKey = hRootKey;
4271+ hRootKey = NULL;
4272+ }
4273+
4274+ dwError = LwRegSetValueExA(hReg, hKeyKey, pszValueName, 0, dwType, pData, cbData);
4275+ BAIL_ON_ERROR(dwError);
4276+
4277+cleanup:
4278+ if (hKeyKey)
4279+ {
4280+ LwRegCloseKey(hReg, hKeyKey);
4281+ hKeyKey = NULL;
4282+ }
4283+
4284+ if (hRootKey)
4285+ {
4286+ LwRegCloseKey(hReg, hRootKey);
4287+ hRootKey = NULL;
4288+ }
4289+
4290+ if (hReg)
4291+ {
4292+ LwRegCloseServer(hReg);
4293+ hReg = NULL;
4294+ }
4295+
4296+ return dwError;
4297+
4298+error:
4299+ goto cleanup;
4300+}
4301+
4302+DWORD
4303+UtilGetValueExA(
4304+ PCSTR pszRoot,
4305+ PCSTR pszKey,
4306+ PCSTR pszValueName,
4307+ DWORD dwType,
4308+ PVOID *ppvData,
4309+ PDWORD pcbData
4310+ )
4311+{
4312+ DWORD dwError = 0;
4313+ DWORD dwActualType = 0;
4314+ PSTR pszValue = NULL;
4315+ char szValue[MAX_VALUE_LENGTH];
4316+ DWORD cbData = sizeof(szValue);
4317+ HANDLE hReg = NULL;
4318+ HKEY hRootKey = NULL;
4319+ HKEY hKeyKey = NULL;
4320+
4321+ dwError = LwRegOpenServer(&hReg);
4322+ BAIL_ON_ERROR(dwError);
4323+
4324+ if (!strcmp(pszRoot, "HKEY_THIS_MACHINE"))
4325+ {
4326+ dwError = LwRegOpenKeyExA(hReg, NULL, HKEY_THIS_MACHINE, 0, KEY_READ, &hRootKey);
4327+ BAIL_ON_ERROR(dwError);
4328+ }
4329+ else
4330+ {
4331+ dwError = LW_ERROR_INVALID_PARAMETER;
4332+ BAIL_ON_ERROR(dwError);
4333+ }
4334+
4335+ if (pszKey && pszKey[0])
4336+ {
4337+ dwError = LwRegOpenKeyExA(hReg, hRootKey, pszKey, 0, KEY_READ,
4338+ &hKeyKey);
4339+ BAIL_ON_ERROR(dwError);
4340+ }
4341+ else
4342+ {
4343+ hKeyKey = hRootKey;
4344+ hRootKey = NULL;
4345+ }
4346+
4347+ dwError = LwRegQueryValueExA(hReg, hKeyKey, pszValueName, 0, &dwActualType,
4348+ (PBYTE)szValue, &cbData);
4349+ BAIL_ON_ERROR(dwError);
4350+
4351+ if (dwActualType != dwType)
4352+ {
4353+ dwError = ERROR_INVALID_PARAMETER;
4354+ BAIL_ON_ERROR(dwError);
4355+ }
4356+
4357+ if (dwType == REG_DWORD && cbData == sizeof(REG_DWORD))
4358+ {
4359+ memcpy(ppvData, szValue, sizeof(REG_DWORD));
4360+ *pcbData = sizeof(REG_DWORD);
4361+ }
4362+ else if (dwType == REG_SZ)
4363+ {
4364+ dwError = LwAllocateString(szValue, &pszValue);
4365+ BAIL_ON_ERROR(dwError);
4366+
4367+ *ppvData = pszValue;
4368+ *pcbData = cbData;
4369+ }
4370+ else if (dwType == REG_MULTI_SZ)
4371+ {
4372+ dwError = LwAllocateMemory(cbData, (PVOID*)&pszValue);
4373+ BAIL_ON_ERROR(dwError);
4374+
4375+ memcpy(pszValue, szValue, cbData);
4376+
4377+ *ppvData = pszValue;
4378+ *pcbData = cbData;
4379+ }
4380+ else
4381+ {
4382+ dwError = ERROR_INVALID_PARAMETER;
4383+ BAIL_ON_ERROR(dwError);
4384+ }
4385+
4386+
4387+cleanup:
4388+ if (hKeyKey)
4389+ {
4390+ LwRegCloseKey(hReg, hKeyKey);
4391+ hKeyKey = NULL;
4392+ }
4393+
4394+ if (hRootKey)
4395+ {
4396+ LwRegCloseKey(hReg, hRootKey);
4397+ hRootKey = NULL;
4398+ }
4399+
4400+ if (hReg)
4401+ {
4402+ LwRegCloseServer(hReg);
4403+ hReg = NULL;
4404+ }
4405+
4406+ return dwError;
4407+
4408+error:
4409+ LW_SAFE_FREE_MEMORY(pszValue);
4410+ goto cleanup;
4411+}
4412+
4413+static
4414+DWORD
4415+AppendCharacter(int c, PSTR *ppszLine, PDWORD pdwMaxSize)
4416+{
4417+ DWORD dwError = 0;
4418+ PSTR pszLine = NULL;
4419+ DWORD dwMaxSize = 0;
4420+ size_t i = 0;
4421+
4422+ if (*ppszLine)
4423+ for (i = 0; (*ppszLine)[i]; i++)
4424+ ;
4425+
4426+ if (!*ppszLine || i + 1 == *pdwMaxSize)
4427+ {
4428+ dwMaxSize = *pdwMaxSize + 16; // Not doing exponential growth
4429+ dwError = LwAllocateMemory(sizeof(char) * dwMaxSize, (PVOID*)&pszLine);
4430+ BAIL_ON_ERROR(dwError);
4431+
4432+ memcpy(pszLine, *ppszLine, *pdwMaxSize);
4433+
4434+ LW_SAFE_FREE_STRING(*ppszLine);
4435+ *ppszLine = pszLine;
4436+ pszLine = NULL;
4437+ *pdwMaxSize = dwMaxSize;
4438+ }
4439+ (*ppszLine)[i] = c;
4440+ (*ppszLine)[i+1] = '\0';
4441+
4442+cleanup:
4443+ return dwError;
4444+
4445+error:
4446+ LW_SAFE_FREE_STRING(pszLine);
4447+ goto cleanup;
4448+}
4449+
4450+static
4451+DWORD
4452+AppendArgument(PSTR pszLine, PSTR **pppszArgs, PDWORD pdwArgs)
4453+{
4454+ DWORD dwError = 0;
4455+ PSTR pszNewLine = NULL;
4456+ PSTR *ppszArgs = NULL;
4457+ DWORD dwArgs = 0;
4458+
4459+ dwError = LwAllocateString(pszLine, &pszNewLine);
4460+ BAIL_ON_ERROR(dwError);
4461+
4462+ dwArgs = *pdwArgs + 1;
4463+ dwError = LwAllocateMemory(sizeof(PSTR) * dwArgs, (PVOID*)&ppszArgs);
4464+ BAIL_ON_ERROR(dwError);
4465+
4466+ memcpy(ppszArgs, *pppszArgs, *pdwArgs * sizeof(*ppszArgs));
4467+ ppszArgs[*pdwArgs] = pszNewLine;
4468+ pszNewLine = NULL;
4469+
4470+ LW_SAFE_FREE_MEMORY(*pppszArgs);
4471+ *pppszArgs = ppszArgs;
4472+ ppszArgs = NULL;
4473+
4474+ *pdwArgs = dwArgs;
4475+
4476+cleanup:
4477+ return dwError;
4478+
4479+error:
4480+ LW_SAFE_FREE_STRING(pszNewLine);
4481+ goto cleanup;
4482+}
4483+
4484+DWORD
4485+UtilParseLine(
4486+ PCSTR pszLine,
4487+ PSTR **pppszArgs,
4488+ PDWORD pdwArgs
4489+ )
4490+{
4491+ DWORD dwError = 0;
4492+ PSTR pszArg = NULL;
4493+ DWORD dwArgMaxSize = 0;
4494+ PSTR *ppszArgs = NULL;
4495+ DWORD dwArgs = 0;
4496+ BOOLEAN bArgument = FALSE;
4497+ BOOLEAN bQuoted = FALSE;
4498+ BOOLEAN bEscaped = FALSE;
4499+ size_t i = 0;
4500+
4501+ dwArgMaxSize = 64;
4502+ dwError = LwAllocateMemory(sizeof(char) * dwArgMaxSize, (PVOID*)&pszArg);
4503+ BAIL_ON_ERROR(dwError);
4504+
4505+ for (i = 0; pszLine[i] && pszLine[i] != '\n' && pszLine[i] != '\r'; i++)
4506+ {
4507+ int c = pszLine[i];
4508+
4509+ if (!bArgument)
4510+ {
4511+ if (c == ' ' || c == '\t')
4512+ continue;
4513+ }
4514+ bArgument = TRUE;
4515+
4516+ if (bEscaped)
4517+ {
4518+ dwError = AppendCharacter(c, &pszArg, &dwArgMaxSize);
4519+ BAIL_ON_ERROR(dwError);
4520+ bEscaped = FALSE;
4521+ }
4522+ else if (c == '\\')
4523+ {
4524+ bEscaped = TRUE;
4525+ }
4526+ else if (bQuoted)
4527+ {
4528+ if (c == '"')
4529+ {
4530+ bQuoted = FALSE;
4531+ bArgument = FALSE;
4532+
4533+ // Terminate argument
4534+ dwError = AppendArgument(pszArg, &ppszArgs, &dwArgs);
4535+ BAIL_ON_ERROR(dwError);
4536+ pszArg[0] = '\0';
4537+ }
4538+ else
4539+ {
4540+ dwError = AppendCharacter(c, &pszArg, &dwArgMaxSize);
4541+ BAIL_ON_ERROR(dwError);
4542+ }
4543+ }
4544+ else if (c == '"')
4545+ {
4546+ bQuoted = TRUE;
4547+
4548+ // Terminate previous argument if there was one.
4549+ if (pszArg && pszArg[0])
4550+ {
4551+ dwError = AppendArgument(pszArg, &ppszArgs, &dwArgs);
4552+ BAIL_ON_ERROR(dwError);
4553+ pszArg[0] = '\0';
4554+ }
4555+ }
4556+ else if (c == ' ' || c == '\t')
4557+ {
4558+ bArgument = FALSE;
4559+
4560+ // Terminate previous argument
4561+ dwError = AppendArgument(pszArg, &ppszArgs, &dwArgs);
4562+ BAIL_ON_ERROR(dwError);
4563+ pszArg[0] = '\0';
4564+ }
4565+ else
4566+ {
4567+ dwError = AppendCharacter(c, &pszArg, &dwArgMaxSize);
4568+ BAIL_ON_ERROR(dwError);
4569+ }
4570+ }
4571+
4572+ if (bEscaped)
4573+ {
4574+ dwError = APP_ERROR_INVALID_ESCAPE_SEQUENCE;
4575+ BAIL_ON_ERROR(dwError);
4576+ }
4577+ if (bQuoted)
4578+ {
4579+ dwError = APP_ERROR_UNTERMINATED_QUOTE;
4580+ BAIL_ON_ERROR(dwError);
4581+ }
4582+ if (pszArg[0])
4583+ {
4584+ dwError = AppendArgument(pszArg, &ppszArgs, &dwArgs);
4585+ BAIL_ON_ERROR(dwError);
4586+ }
4587+
4588+ *pppszArgs = ppszArgs;
4589+ *pdwArgs = dwArgs;
4590+
4591+cleanup:
4592+ LW_SAFE_FREE_STRING(pszArg);
4593+ return dwError;
4594+
4595+error:
4596+
4597+ LW_SAFE_FREE_STRING(pszArg);
4598+ for (i = 0; i < dwArgs; i++)
4599+ {
4600+ LW_SAFE_FREE_STRING(ppszArgs[i]);
4601+ }
4602+ LW_SAFE_FREE_MEMORY(ppszArgs);
4603+ goto cleanup;
4604+}
4605+
4606+DWORD
4607+UtilReadLine(
4608+ FILE* pStream,
4609+ PSTR* ppszLine
4610+ )
4611+{
4612+ DWORD dwError = 0;
4613+ ssize_t sSize = 0, sCapacity = 0;
4614+ PSTR pszBuffer = NULL;
4615+ // Do not free
4616+ PSTR pszNewBuffer = NULL;
4617+
4618+ do
4619+ {
4620+ // There is not enough space. Allocate a larger buffer
4621+ sCapacity = sSize*2 + 10;
4622+ dwError = LwReallocMemory(
4623+ pszBuffer,
4624+ OUT_PPVOID(&pszNewBuffer),
4625+ sCapacity + 1);
4626+ BAIL_ON_ERROR(dwError);
4627+ pszBuffer = pszNewBuffer;
4628+
4629+ // Read as much as the stream will give us up to the space in the
4630+ // buffer.
4631+ errno = 0;
4632+ if (fgets(pszBuffer + sSize, sCapacity - sSize, pStream) == NULL)
4633+ {
4634+ dwError = LwMapErrnoToLwError(errno);
4635+ if (dwError == 0)
4636+ {
4637+ dwError = ERROR_HANDLE_EOF;
4638+ }
4639+ BAIL_ON_ERROR(dwError);
4640+ }
4641+
4642+ sSize += strlen(pszBuffer + sSize);
4643+ }
4644+ // While the whole buffer is used and it does not end in a newline
4645+ while(sSize == sCapacity - 1 && pszBuffer[sSize-1] != '\n');
4646+
4647+ if (sSize == 0)
4648+ {
4649+ dwError = ERROR_HANDLE_EOF;
4650+ BAIL_ON_ERROR(dwError);
4651+ }
4652+ if (pszBuffer[sSize-1] == '\n')
4653+ pszBuffer[sSize-1] = '\0';
4654+
4655+ *ppszLine = pszBuffer;
4656+
4657+cleanup:
4658+ return dwError;
4659+
4660+error:
4661+ LW_SAFE_FREE_STRING(pszBuffer);
4662+ goto cleanup;
4663+}
4664+
4665+DWORD
4666+UtilAllocateEscapedString(
4667+ PCSTR pszStr,
4668+ PSTR *ppszEscapedStr
4669+ )
4670+{
4671+ DWORD dwError = 0;
4672+ const PCSTR pszEscapeChars = "\\\"";
4673+ DWORD i, j;
4674+ PSTR pszEscapedStr = NULL;
4675+ DWORD dwCount = 0;
4676+
4677+ for (i = 0; pszStr[i]; i++)
4678+ {
4679+ if (strchr(pszEscapeChars, pszStr[i]) != NULL)
4680+ dwCount++;
4681+ dwCount++;
4682+ }
4683+ dwCount++;
4684+
4685+ dwError = LwAllocateMemory(dwCount, (PVOID)&pszEscapedStr);
4686+ BAIL_ON_ERROR(dwError);
4687+
4688+ for (i = 0, j = 0; pszStr[i]; i++)
4689+ {
4690+ if (strchr(pszEscapeChars, pszStr[i]) != NULL)
4691+ {
4692+ pszEscapedStr[j++] = '\\';
4693+ }
4694+ pszEscapedStr[j++] = pszStr[i];
4695+ }
4696+ pszEscapedStr[j] = '\0';
4697+
4698+ *ppszEscapedStr = pszEscapedStr;
4699+
4700+cleanup:
4701+ return dwError;
4702+
4703+error:
4704+ LW_SAFE_FREE_MEMORY(pszEscapedStr);
4705+ goto cleanup;
4706+}
4707
4708=== added file 'lwconfig/src/util.h'
4709--- lwconfig/src/util.h 1970-01-01 00:00:00 +0000
4710+++ lwconfig/src/util.h 2011-02-24 04:27:55 +0000
4711@@ -0,0 +1,95 @@
4712+/*
4713+* Copyright (c) Likewise Software. All rights reserved.
4714+*
4715+* This program is free software; you can redistribute it and/or modify
4716+* it under the terms of the GNU General Public License as published by
4717+* the Free Software Foundation; either version 2 of the License, or (at
4718+* your option) any later version.
4719+*
4720+* This program is distributed in the hope that it will be useful, but
4721+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4722+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4723+* for more details. You should have received a copy of the GNU General
4724+* Public License along with this program. If not, see
4725+* <http://www.gnu.org/licenses/>.
4726+*
4727+* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
4728+* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
4729+* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
4730+* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
4731+* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
4732+* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
4733+* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
4734+* license@likewise.com
4735+*/
4736+#ifndef LWCONFIG_UTIL_H
4737+#define LWCONFIG_UTIL_H
4738+
4739+#include "includes.h"
4740+
4741+DWORD
4742+UtilAllocateMultistring(
4743+ PCSTR *ppszValues,
4744+ DWORD dwValues,
4745+ PSTR *ppszValue
4746+ );
4747+
4748+DWORD
4749+UtilMultistringLength(
4750+ PCSTR pszValue
4751+ );
4752+
4753+DWORD
4754+UtilDuplicateMultistring(
4755+ PCSTR pszValue,
4756+ PSTR *ppszValue
4757+ );
4758+
4759+DWORD
4760+UtilParseRegName(
4761+ PCSTR pszPath,
4762+ PSTR *ppszRoot,
4763+ PSTR *ppszKey,
4764+ PSTR *ppszValueName
4765+ );
4766+
4767+DWORD
4768+UtilSetValueExA(
4769+ PCSTR pszRoot,
4770+ PCSTR pszKey,
4771+ PCSTR pszValueName,
4772+ DWORD dwType,
4773+ const BYTE *pData,
4774+ DWORD cbData
4775+ );
4776+
4777+DWORD
4778+UtilGetValueExA(
4779+ PCSTR pszRoot,
4780+ PCSTR pszKey,
4781+ PCSTR pszValueName,
4782+ DWORD dwType,
4783+ PVOID *ppvData,
4784+ PDWORD pcbData
4785+ );
4786+
4787+DWORD
4788+UtilParseLine(
4789+ PCSTR pszLine,
4790+ PSTR **pppszArgs,
4791+ PDWORD pdwArgs
4792+ );
4793+
4794+DWORD
4795+UtilReadLine(
4796+ FILE* pStream,
4797+ PSTR* ppszLine
4798+ );
4799+
4800+DWORD
4801+UtilAllocateEscapedString(
4802+ PCSTR pszStr,
4803+ PSTR *ppszEscapedStr
4804+ );
4805+
4806+#endif

Subscribers

People subscribed via source and target branches

to all changes: